home *** CD-ROM | disk | FTP | other *** search
/ Chip 2007 January, February, March & April / Chip-Cover-CD-2007-02.iso / Pakiet bezpieczenstwa / mini Pentoo LiveCD 2006.1 / mpentoo-2006.1.iso / livecd.squashfs / usr / bin / scapy < prev    next >
Text File  |  2006-03-29  |  379KB  |  10,979 lines

  1. #! /usr/bin/env python
  2.  
  3. #############################################################################
  4. ##                                                                         ##
  5. ## scapy.py --- Interactive packet manipulation tool                       ##
  6. ##              see http://www.secdev.org/projects/scapy/                  ##
  7. ##              for more informations                                      ##
  8. ##                                                                         ##
  9. ## Copyright (C) 2003  Philippe Biondi <phil@secdev.org>                   ##
  10. ##                                                                         ##
  11. ## This program is free software; you can redistribute it and/or modify it ##
  12. ## under the terms of the GNU General Public License version 2 as          ##
  13. ## published by the Free Software Foundation; version 2.                   ##
  14. ##                                                                         ##
  15. ## This program is distributed in the hope that it will be useful, but     ##
  16. ## WITHOUT ANY WARRANTY; without even the implied warranty of              ##
  17. ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU       ##
  18. ## General Public License for more details.                                ##
  19. ##                                                                         ##
  20. #############################################################################
  21.  
  22. #
  23. # $Log: scapy.py,v $
  24. # Revision 1.0.4.1  2006/03/17 12:48:28  pbi
  25. # Release 1.0.4
  26. #
  27. # Revision 1.0.3.34  2006/03/17 12:48:02  pbi
  28. # - added docstring for TracerouteResult.trace3D()
  29. #
  30. # Revision 1.0.3.33  2006/03/14 19:05:05  pbi
  31. # - added equality tests between two packets.
  32. #
  33. # Revision 1.0.3.32  2006/03/14 18:35:41  pbi
  34. # - added a timeout parameter to sniff()
  35. #
  36. # Revision 1.0.3.31  2006/03/14 17:48:30  pbi
  37. # - removed deprecated Packet.send()
  38. #
  39. # Revision 1.0.3.30  2006/03/14 17:46:03  pbi
  40. # - fix indentation quirk
  41. #
  42. # Revision 1.0.3.29  2006/03/14 15:12:59  pbi
  43. # - removed forgotten print in Packet.trace3D()
  44. #
  45. # Revision 1.0.3.28  2006/03/12 18:00:42  pbi
  46. # - made Packet.getlayer() and Packet.haslayer() also work with class names
  47. # - got rid of Packet.haslayer_str()
  48. #
  49. # Revision 1.0.3.27  2006/03/12 17:56:14  pbi
  50. # - improved Packet.getlayer(), Packet.haslayer() and Packet.haslayer_str()
  51. #   to look into PacketFields.
  52. #
  53. # Revision 1.0.3.26  2006/03/09 22:25:00  pbi
  54. # - removed bad loop in L3PacketSocket and L2Socket when discarding outgoing packets (W. McVey)
  55. #
  56. # Revision 1.0.3.25  2006/03/09 22:15:38  pbi
  57. # - added Ctrl-Click to TracerouteResult.trace3D() to scan an IP
  58. #
  59. # Revision 1.0.3.24  2006/02/28 18:33:32  pbi
  60. # - added a "trans" parameter to colgen to handle automatic specific conversions into color object
  61. # - used colgen() in Packet.canvas_dump()
  62. #
  63. # Revision 1.0.3.23  2006/02/28 18:24:27  pbi
  64. # - removed makecol() from TracerouteResult.graph()
  65. #
  66. # Revision 1.0.3.22  2006/02/28 18:23:46  pbi
  67. # - turned makecol() TracerouteResult.graph()' internal function into colgen() generator tool
  68. #
  69. # Revision 1.0.3.21  2006/02/28 18:04:10  pbi
  70. # - added TracerouteResult.trace3D() to have a 3D traceroute visualization with VPython
  71. #
  72. # Revision 1.0.3.20  2006/02/27 18:03:46  pbi
  73. # - added get_trace() method to TraceouteResult() to extract traceroute data
  74. #
  75. # Revision 1.0.3.19  2006/02/27 15:13:36  pbi
  76. # - Fixed Dot11Beacon's fields' endianness (G. Lukas)
  77. #
  78. # Revision 1.0.3.18  2006/02/27 15:08:25  pbi
  79. # - factorised tex_escape() function from ps/pdfdump()
  80. # - added LatexTheme2 for autorun_get_latex_interactive_session()
  81. # - escape stuff in autorun_get_latex_interactive_session()
  82. #
  83. # Revision 1.0.3.17  2006/02/22 11:33:34  pbi
  84. # - added config.prog to reference external program pathes
  85. #
  86. # Revision 1.0.3.16  2006/02/22 11:19:26  pbi
  87. # - added afterglow clone attempt (http://sourceforge.net/projects/afterglow)
  88. #
  89. # Revision 1.0.3.15  2006/02/22 11:14:39  pbi
  90. # - added prog parameter to do_graph()
  91. #
  92. # Revision 1.0.3.15  2006/02/21 12:45:00  pbi
  93. # - added prog paramter to do_graph()
  94. #
  95. # Revision 1.0.3.14  2006/02/21 12:21:44  pbi
  96. # - removed hard dependancy on libreadline. Now works even if no libreadline is installed
  97. #
  98. # Revision 1.0.3.13  2006/02/19 14:06:28  pbi
  99. # - fixed show()'s indentation
  100. #
  101. # Revision 1.0.3.12  2006/02/19 13:49:18  pbi
  102. # - many docstrings corrections
  103. #
  104. # Revision 1.0.3.11  2006/02/17 16:29:38  pbi
  105. # - improved show() to use an exploded view for fields which hold packets
  106. # - added show_indent flag to Packet() that can be overloaded to 0 for layers that are followed by peers
  107. #   and for whom indentation in show() is not desired
  108. #
  109. # Revision 1.0.3.10  2006/02/17 11:14:16  pbi
  110. # - changed conversation parameter to group getsrc/getdst into getsrcdst
  111. #
  112. # Revision 1.0.3.9  2006/02/17 10:57:53  pbi
  113. # - added docstrings for PacketList
  114. #
  115. # Revision 1.0.3.8  2006/02/16 15:45:51  pbi
  116. # - added docstrings to sr*(), wrpcap(), rdpcap()
  117. #
  118. # Revision 1.0.3.7  2006/02/16 15:37:44  pbi
  119. # - fixed conf.BTsocket assignment BluetoothSocket BluetoothL2CAPSocket
  120. #
  121. # Revision 1.0.3.6  2006/02/16 15:11:13  pbi
  122. # - added docstrings to many methods of Packet
  123. #
  124. # Revision 1.0.3.5  2006/02/16 14:09:07  pbi
  125. # - added BluetoothHCIsocket
  126. # - added L2socket to sniff
  127. # - added HCI_Hdr, L2CAP_Hdr layers, moved L2CAP to L2CAP_HdrCmd
  128. #
  129. # Revision 1.0.3.4  2006/02/12 01:06:52  pbi
  130. # - initialize payload's underlayer before payload's dissection
  131. #
  132. # Revision 1.0.3.3  2006/01/29 00:06:48  pbi
  133. # - added shortcut to PacketList to extract a given protocol with []. ex : lst[ICMP]
  134. #
  135. # Revision 1.0.3.2  2006/01/28 23:52:21  pbi
  136. # - removed useless (and racy) __del__() methods from PcapReader and PcapWriter
  137. #
  138. # Revision 1.0.3.1  2006/01/28 14:32:55  pbi
  139. # Release 1.0.3
  140. #
  141. # Revision 1.0.2.37  2006/01/28 13:14:25  pbi
  142. # - tweaked ls() for add-on classes to appear in the listing
  143. #
  144. # Revision 1.0.2.36  2006/01/28 13:02:15  pbi
  145. # - replaced remaining occurences of use of display() [deprecated, use show()]
  146. # - removed URL from dummy IPv6 classes names
  147. #
  148. # Revision 1.0.2.35  2006/01/17 18:02:42  pbi
  149. # - finished Packet.canvas_dup() escape() function. Every char is correctly translated into TeX
  150. #
  151. # Revision 1.0.2.34  2006/01/15 13:15:57  pbi
  152. # -added information-request and information-response to ICMP types (J. Bowie)
  153. #
  154. # Revision 1.0.2.33  2006/01/15 13:15:16  pbi
  155. # - fixed NetBIOSNameField incorrect length calculation (J. Bowie)
  156. #
  157. # Revision 1.0.2.32  2006/01/14 16:54:29  pbi
  158. # - added missing _IPv6optionHearder dummy class
  159. # - removed useless IPv6_instace() function
  160. #
  161. # Revision 1.0.2.31  2006/01/12 11:02:51  pbi
  162. # - fixed 1.0.2.29 collision fix (s/mtu/mtu_present/)
  163. #
  164. # Revision 1.0.2.30  2006/01/11 17:45:45  pbi
  165. # - fixed endianness problems in PcapReader()
  166. # - fixed PcapReader.read_all()
  167. # - added missing try/except to PcapReader.read_packet()
  168. # - removed PcapReader.read_PacketList() (read_all() already returns a PacketList)
  169. # - removed debug "print" from PcapWriter()
  170. # - added endianness parameter in PcapWriter()
  171. #
  172. # Revision 1.0.2.29  2006/01/11 17:00:01  pbi
  173. # - added Solaris support (wit help from S. Despret)
  174. # - added Solaris missing IPPROTO_GRE
  175. # - changed read_routes() to work with Solaris netstat
  176. # - fixed read_route() local variable collision (mtu became mtu_present)
  177. # - changed variable fl to flg
  178. #
  179. # Revision 1.0.2.28  2006/01/05 17:49:17  pbi
  180. # - re-added indentation in Packet.show(). Can be tweaked with "indent" parameter
  181. #
  182. # Revision 1.0.2.27  2006/01/04 15:04:17  pbi
  183. # - added missing try/except arround dissection in rdpcap()
  184. #
  185. # Revision 1.0.2.26  2005/12/23 00:51:51  pbi
  186. # - strengthened DNS disassembly
  187. #
  188. # Revision 1.0.2.25  2005/12/23 00:11:09  pbi
  189. # - have scapy work if Python IPv6 support is not compiled in socketmodule
  190. #
  191. # Revision 1.0.2.24  2005/12/23 00:08:50  pbi
  192. # - aliased socket.inet_ntoa into local namespace for consistency with other ?to?
  193. #
  194. # Revision 1.0.2.23  2005/12/22 17:58:08  pbi
  195. # - fixed and enhanced autorun_commands()
  196. #
  197. # Revision 1.0.2.22  2005/12/21 23:00:16  pbi
  198. # - fixed bug introduced by fix 1.0.2.19 on _
  199. #
  200. # Revision 1.0.2.21  2005/12/21 22:58:45  pbi
  201. # - added Packet.get_field() to get a field instance from its name
  202. # - modified some fields to use Packet.get_field() instead of a complex operation
  203. #
  204. # Revision 1.0.2.20  2005/12/19 12:43:52  pbi
  205. # - added FieldListField to create arrays of fields whose number is given in a FieldLenField
  206. #
  207. # Revision 1.0.2.19  2005/12/18 22:46:35  pbi
  208. # - fixed uninitialized _ in autorun_commands()
  209. #
  210. # Revision 1.0.2.18  2005/12/17 11:27:05  pbi
  211. # - Changed ColorTheme class be usable
  212. # - Added NoTheme class
  213. # - added autorun_get_text_interactive_session()
  214. # - added autorun_get_ansi_interactive_session()
  215. # - added autorun_get_latex_interactive_session() (miss some special chars filtering)
  216. #
  217. # Revision 1.0.2.17  2005/12/15 15:13:58  pbi
  218. # - IPv6 migration step 1: integrate some IPv6 routing stuff for IPv6 fork to work
  219. #   as an add-on
  220. #
  221. # Revision 1.0.2.16  2005/12/07 18:02:26  pbi
  222. # - added fallbacks if tcpdump can't be run and libpcap is not used
  223. #
  224. # Revision 1.0.2.15  2005/12/07 17:44:11  pbi
  225. # - fixed socket filter pushing for x86_64 arch. (W. Robinet)
  226. #
  227. # Revision 1.0.2.14  2005/12/06 16:41:30  pbi
  228. # - added conf.check_TCPerror_seqack (default 0) to relax ICMP error matching for TCP
  229. #   packets (some broken PIX play with sequence numbers and forget to tidy them up)
  230. #
  231. # Revision 1.0.2.13  2005/11/27 00:09:30  pbi
  232. # - added code to run interactive sessions automatically
  233. #
  234. # Revision 1.0.2.12  2005/11/26 11:33:55  pbi
  235. # - catch exceptions in ColorPrompt from bad color theme to avoid
  236. #   program termination
  237. #
  238. # Revision 1.0.2.11  2005/11/26 11:10:44  pbi
  239. # - added class HTMLTheme2 with trigram instead of '<' and '>' to easily convert others into < and >
  240. #
  241. # Revision 1.0.2.10  2005/11/20 16:23:01  pbi
  242. # - improved a bit error handling of import dnet/pcap
  243. # - made INFO messages for missing files a bit more clear
  244. #
  245. # Revision 1.0.2.9  2005/11/19 08:39:09  pbi
  246. # - handle API change between pylibpcap 0.4 and 0.5
  247. #
  248. # Revision 1.0.2.8  2005/11/17 11:05:56  pbi
  249. # - changed Packet.sprintf() format string specificator to accept only the
  250. #   field name and take the currend layer
  251. #
  252. # Revision 1.0.2.7  2005/11/17 10:24:53  pbi
  253. # - added onlyasc parameter to linehexdump()
  254. # - added onlyasc parameter to fragleak() and fragleak2()
  255. #
  256. # Revision 1.0.2.6  2005/11/15 04:55:11  pbi
  257. # - added Packet.command() to go from a packet instance to the Scapy command to generate it
  258. #
  259. # Revision 1.0.2.5  2005/11/15 03:04:51  pbi
  260. # - write history in an atexit registered function
  261. #
  262. # Revision 1.0.2.4  2005/11/15 02:58:44  pbi
  263. # - fixed Enum fields for them to work with lists of values
  264. #
  265. # Revision 1.0.2.3  2005/11/09 19:56:42  pbi
  266. # - added a ColorTheme.__repr__() to fix objects that used it, like conf object!
  267. #
  268. # Revision 1.0.2.2  2005/11/09 18:26:57  pbi
  269. # - fixed itom() to return positive values even for big endian platforms
  270. # - fixed RandIP default __init__ parameter to be 0.0.0.0/0 instead of 0/0
  271. #
  272. # Revision 1.0.2.1  2005/11/07 14:04:39  pbi
  273. # release 1.0.2
  274. #
  275. # Revision 1.0.1.13  2005/11/07 14:00:54  pbi
  276. # - fixed Dot11Auth.seqnum to be little endian
  277. # - added Dot11Auth.answers()
  278. #
  279. # Revision 1.0.1.12  2005/11/07 13:39:31  pbi
  280. # - fixed some stuff in the LaTeX color theme
  281. #
  282. # Revision 1.0.1.11  2005/11/07 13:38:36  pbi
  283. # - added timeout parameter to fragleak()
  284. # - created fragleak2()
  285. #
  286. # Revision 1.0.1.10  2005/11/07 13:37:20  pbi
  287. # - fixed LLC/SNAP binding to overload LLC.ctrl with 3
  288. #
  289. # Revision 1.0.1.9  2005/11/07 13:35:12  pbi
  290. # - changed Dot11.summary() to show src > dst
  291. # - added Dot11.answers()
  292. #
  293. # Revision 1.0.1.8  2005/11/07 13:33:43  pbi
  294. # - added DNS.answsers()
  295. #
  296. # Revision 1.0.1.7  2005/11/07 13:33:19  pbi
  297. # - added SignedIntField() and LESignedIntField
  298. # - converted PrismHeader's "signal" field to signed
  299. #
  300. # Revision 1.0.1.6  2005/11/01 12:22:02  pbi
  301. # - added hint_iface parameter to sendp()
  302. # - used hint_iface in arpcachepoison()
  303. #
  304. # Revision 1.0.1.5  2005/10/31 12:29:09  pbi
  305. # - added ConditionalField to wrap a field and apply a condition to its presense
  306. # - added NewDefaultValues metaclass to create new Packet classes from old ones
  307. #   with new default default values
  308. # - added GRE protocol from rfc2784. (need more work for rfc1701)
  309. #
  310. # Revision 1.0.1.4  2005/10/27 15:12:32  pbi
  311. # - created VolatileValue class to handle volatile values like RandomField
  312. # - redesigned inheritence of random fields arround VolatileValue
  313. # - added DelayedEval() volatile value
  314. #
  315. # Revision 1.0.1.3  2005/10/27 14:59:11  pbi
  316. # - Changed color themes handling. Now LatexTheme and HTMLTheme are not ugly hacks anymore.
  317. #
  318. # Revision 1.0.1.2  2005/10/26 16:15:06  pbi
  319. # - added CharEnumField()
  320. # - declared s2i and i2s in EnumField before calling superclass' contructor
  321. #
  322. # Revision 1.0.1.1  2005/10/25 07:49:35  pbi
  323. # Release 1.0.1
  324. #
  325. # Revision 1.0.0.61  2005/10/25 07:48:48  pbi
  326. # - added rebuild option to Packet.p{s|df}dump() to dump a packet as-is
  327. #
  328. # Revision 1.0.0.60  2005/10/23 18:20:30  pbi
  329. # - PacketList.sr() return ( (matched couples), (unmatched packets) ) from the packet list
  330. #
  331. # Revision 1.0.0.59  2005/10/23 17:15:34  pbi
  332. # - added layer_shift option to every p{s|df}dump() method to explode hexa dump by layers
  333. #
  334. # Revision 1.0.0.58  2005/10/23 17:09:29  pbi
  335. # - return a loopback route when no default route is present. XXX: linux specific!
  336. #
  337. # Revision 1.0.0.57  2005/10/23 17:07:59  pbi
  338. # - split bind_layers() into bind_top_down() and bind_bottom_up()
  339. #
  340. # Revision 1.0.0.56  2005/10/23 16:57:26  pbi
  341. # - fixed dissection errors exception management when conf.debug_dissector is true
  342. #
  343. # Revision 1.0.0.55  2005/10/23 16:56:00  pbi
  344. # - made MACField's default value to be "00:00:00:00:00:00"
  345. # - fixed DestMACField's default value to be "ff:ff:ff:ff:ff:ff"
  346. #
  347. # Revision 1.0.0.54  2005/10/23 16:54:00  pbi
  348. # - fixed Field.randval() to work with string formats and modifiers
  349. # - fixed fuzz() not to overload default value if field's proposed randval is None
  350. #
  351. # Revision 1.0.0.53  2005/10/17 16:03:36  pbi
  352. # - uniformized to "lfilter" the paramter name for lambda expressions used as filters
  353. # - removed a superfluous line in crc32()
  354. #
  355. # Revision 1.0.0.52  2005/10/15 13:17:18  pbi
  356. # - AutoTime() and IntAutoTime() classes that give a field a time dependant value
  357. # - PacketList.timeskew_graph() should work on SndRcvList()
  358. #
  359. # Revision 1.0.0.51  2005/10/08 20:52:45  pbi
  360. # - added StreamSocket supersocket to emulate a datagram socket on a stream
  361. #   socket that supports MSG_PEEK and whose base layer class knows its own size
  362. #   and put the remaining in Padding()
  363. #
  364. # Revision 1.0.0.50  2005/10/08 12:46:56  pbi
  365. # - remove useless routes in netstat -rn output (P. Lalet)
  366. #
  367. # Revision 1.0.0.49  2005/10/08 12:41:23  pbi
  368. # - fixed netmask calculations (P. Lalet)
  369. #
  370. # Revision 1.0.0.48  2005/10/08 11:21:28  pbi
  371. # - use color for packet numbering in nsummary() et al.
  372. #
  373. # Revision 1.0.0.47  2005/10/06 12:57:25  pbi
  374. # - fixed MAC addresses calculation when IP is a Gen() instance (G. Valadon)
  375. #
  376. # Revision 1.0.0.46  2005/10/06 12:44:51  pbi
  377. # - added route.get_if_bcast() to get interface's broadcast address (F. Raynal)
  378. # - added a check in getmacbyip() to give a broadcast MAC for a broadcast IP
  379. # - added sndrcv() (thus sr*() family)  "multi" parameter to accept many answers
  380. #   from one stimulus. (If stimulus uses a broadcast dst address, you'll need
  381. #   to set conf.checkIPaddr=0)
  382. #
  383. # Revision 1.0.0.45  2005/10/06 12:03:46  pbi
  384. # - changed sys.exit() into os._exit() in sndrcv() to prevent children to flush files buffers
  385. #   that would be written a second time by the parent (SJ Murdoch)
  386. #
  387. # Revision 1.0.0.44  2005/10/06 11:44:48  pbi
  388. # - worked arround (I hope) all FreeBSD/MacOS/pcap issues (look at pcap_get_selectable_fd() note of pcap8 manpage).
  389. #   Thus no more active waits or unseen packets. Still problems to interrupt a capture with ^C on some FreeBSD kernels :(
  390. #
  391. # Revision 1.0.0.43  2005/10/05 11:51:33  pbi
  392. # - added nofilter option to supersockets to handle ethertype filtering for non-linux stuff
  393. #   and for ARP resolution to bypass conf.except_filter
  394. #
  395. # Revision 1.0.0.42  2005/10/05 11:28:14  pbi
  396. # - added RandMAC()
  397. # - added early support for fuzzing
  398. # - added fuzz()
  399. #
  400. # Revision 1.0.0.41  2005/10/05 11:14:57  pbi
  401. # - modified Packet.__iter__ to also evaluate random defaults fields
  402. #
  403. # Revision 1.0.0.40  2005/10/05 11:11:56  pbi
  404. # - filtered more characters for LaTeX in ps/pdf dump
  405. # - removed character that has magically appeared in DHCP_am
  406. #
  407. # Revision 1.0.0.39  2005/10/05 11:08:32  pbi
  408. # - fixed StrFixedLenField.addfield()
  409. #
  410. # Revision 1.0.0.38  2005/10/05 11:06:51  pbi
  411. # - overloaded RandFields repr() to give the class name
  412. # - added RandLong()
  413. # - added RandBin() to be RandString() for all chars
  414. # - added RandTermString()
  415. # - added RandIP default template to be "0/0"
  416. #
  417. # Revision 1.0.0.37  2005/10/05 11:01:20  pbi
  418. # - more tests in DHCP_am.make_reply() to handle garbage in
  419. #
  420. # Revision 1.0.0.36  2005/09/24 14:37:51  pbi
  421. # - added a "padding" option to TracerouteResult.graph() to show routers that pad
  422. #
  423. # Revision 1.0.0.35  2005/09/24 14:32:40  pbi
  424. # - added Packet.psdump() and Packet.pdfdump()
  425. # - added PacketList.psdump() and PacketList.pdfdump()
  426. #
  427. # Revision 1.0.0.34  2005/09/24 14:30:15  pbi
  428. # - ability to change the BPF filter in traceroute()
  429. #
  430. # Revision 1.0.0.33  2005/09/24 14:29:30  pbi
  431. # - completed PrismHeader layer
  432. #
  433. # Revision 1.0.0.32  2005/09/24 14:27:27  pbi
  434. # - deprecated "packet.haslayer(l)" by "l in Packet"
  435. # - deprecated "Packet.getlayer(l)" by "Packet[l]"
  436. #
  437. # Revision 1.0.0.31  2005/09/24 14:25:01  pbi
  438. # - better error message if gnuplot wrapper is missing
  439. # - fixed subclass test in dissection error treatment
  440. # - fixed Dot11Elt summary
  441. # - fixed __sr_loop() to prevent stats calc if no packet have been received
  442. # - fixed sniff() to break loop at the end of reading a file (offline optoin)
  443. #
  444. # Revision 1.0.0.30  2005/09/13 16:03:47  pbi
  445. # - added Dot11Elt.mysummary() for SSID displaying
  446. # - fixed Enum*.i2repr()
  447. #
  448. # Revision 1.0.0.29  2005/09/13 16:02:35  pbi
  449. # - fix build of packets with more than one padding
  450. #
  451. # Revision 1.0.0.28  2005/09/12 16:14:41  pbi
  452. # - new hexdump() which displays offsets
  453. #
  454. # Revision 1.0.0.27  2005/09/12 14:56:31  pbi
  455. # - new summary() and mysummary() semantic (backward compatible!) to enable more than one class to be expanded.
  456. #   The higher gives its dependances along with its own summary
  457. #
  458. # Revision 1.0.0.26  2005/09/12 14:03:10  pbi
  459. # - added ip.dst in ICMP summary()
  460. #
  461. # Revision 1.0.0.25  2005/09/12 13:25:22  pbi
  462. # - added post_dissection() method, called at the end of the dissection, when the packet is ready
  463. # - added default_payload_class() called when layer bonds are not sufficient
  464. # - improved/fixed conf.debug_dissector() which failed when guess_payload_class() returned None
  465. #
  466. # Revision 1.0.0.24  2005/09/08 14:13:36  pbi
  467. # - added RandIP()
  468. #
  469. # Revision 1.0.0.23  2005/09/08 05:29:23  pbi
  470. # - added conf.debug_dissecto checks where it was missing in SuperSockets
  471. # - Slice pcap object only once we know its not None ! (N. Peterson)
  472. #
  473. # Revision 1.0.0.22  2005/09/06 17:08:47  pbi
  474. # - made AnsweringMachine() callable instead of using the run() method
  475. #
  476. # Revision 1.0.0.21  2005/09/06 17:05:19  pbi
  477. # - new logging/warning facility using the logging module
  478. #
  479. # Revision 1.0.0.20  2005/08/28 18:01:12  pbi
  480. # - 802.11 tweaks
  481. #
  482. # Revision 1.0.0.19  2005/08/28 18:00:14  pbi
  483. # - added Packet.decode_payload_as()
  484. #
  485. # Revision 1.0.0.18  2005/08/28 17:51:05  pbi
  486. # - Added XShortEnumField()
  487. #
  488. # Revision 1.0.0.17  2005/08/17 18:11:13  pbi
  489. # - fixed crc32() computation for big endian systems
  490. #
  491. # Revision 1.0.0.16  2005/08/17 12:54:47  pbi
  492. # - fix regression introduced in 1.0.0.4 (netstat parsing)
  493. #
  494. # Revision 1.0.0.15  2005/08/16 17:00:35  pbi
  495. # - fixed socket creation/attach filter race condition for L2Socket and L3PacketSocket.
  496. #   No more packets shoud go through the filter.
  497. #
  498. # Revision 1.0.0.14  2005/08/16 16:58:59  pbi
  499. # - don't return outgoing packets in L2Socket and L3PacketSocket
  500. # - L2Socket and L3PacketSocket don't catch the exception if conf.dissector=1
  501. #
  502. # Revision 1.0.0.13  2005/08/16 16:56:09  pbi
  503. # - enhanced Packet.summary() code
  504. #
  505. # Revision 1.0.0.12  2005/08/16 16:53:31  pbi
  506. # - keep tcp/udp ports numeric in traceroute result
  507. #
  508. # Revision 1.0.0.11  2005/08/15 09:27:45  pbi
  509. # - added NTP.mysummary()
  510. #
  511. # Revision 1.0.0.10  2005/08/15 09:18:56  pbi
  512. # - fixed Ether.summary() (P. Lalet)
  513. #
  514. # Revision 1.0.0.9  2005/08/10 22:18:25  pbi
  515. # - moved code to build answering machines' functions into a metaclass
  516. #
  517. # Revision 1.0.0.8  2005/08/10 20:05:45  pbi
  518. # - added MobileIP protocol (rfc3344 and friends) (B. Andersson)
  519. #
  520. # Revision 1.0.0.7  2005/08/10 20:01:56  pbi
  521. # - changed Ether.mysummary() (P. Lalet)
  522. # - Update of Sebek protocols (P. Lalet)
  523. #
  524. # Revision 1.0.0.6  2005/08/10 19:53:19  pbi
  525. # - fix problem in declaraion of answering machine functions
  526. #
  527. # Revision 1.0.0.5  2005/08/10 15:43:03  pbi
  528. # - added resolution of numbers from /etc/ethertypes, /etc/protocols and
  529. #   /etc/services (P. Lalet)
  530. # - tweaked some mysummary() accordingly
  531. #
  532. # Revision 1.0.0.4  2005/08/10 14:48:06  pbi
  533. # - Better netstat parsing for OpenBSD (P. Lalet)
  534. #
  535. # Revision 1.0.0.3  2005/08/10 14:41:21  pbi
  536. # - fixed regression introduced by previous patch : Gen and Packet are not
  537. #   classes anymore but types.
  538. #
  539. # Revision 1.0.0.2  2005/08/09 21:40:57  pbi
  540. # - added ChangeDefaultValues metaclass to easily make a variant of a protocol
  541. #
  542. # Revision 1.0.0.1  2005/08/09 18:30:10  pbi
  543. # Release 1.0.0
  544. #
  545. # Revision 1.0  2005/08/09 18:26:09  pbi
  546. # 1.0 release
  547. #
  548. # Revision 0.9.17.110  2005/08/09 18:19:17  pbi
  549. # - nothing
  550. #
  551. # Revision 0.9.17.109  2005/08/08 13:57:16  pbi
  552. # - replaced use of __builtins__ by globals()
  553. # - promiscuous mode is now default mode
  554. # - added HTML color theme
  555. #
  556. # Revision 0.9.17.108  2005/08/05 14:12:48  pbi
  557. # - fix: IP fragmentation offset needs to be 0 for payload to be decoded
  558. #   (actually fixed in 0.9.17.106)
  559. #
  560. # Revision 0.9.17.107  2005/08/05 14:04:03  pbi
  561. # - added 'filter' parameter to PacketList.padding()
  562. # - added PacketList.nzpadding() method
  563. # - added 'lfilter' parameter to sniff()
  564. #
  565. # Revision 0.9.17.106  2005/08/05 14:02:19  pbi
  566. # - removed scapy module reloading to prepare interactive mode
  567. # - tweaked interact() function, now fully functionnal
  568. #
  569. # Revision 0.9.17.105  2005/07/20 16:24:06  pbi
  570. # - small fix nmap database class
  571. #
  572. # Revision 0.9.17.104  2005/07/20 16:22:51  pbi
  573. # - modified Packet.guess_payload_class() semantic : added the payload as parameter
  574. # - fixed TCP.answers() to take in account length of payload
  575. # - added timeout arg to arping()
  576. #
  577. # Revision 0.9.17.103  2005/06/07 10:18:27  pbi
  578. # - added a try/catch for get_if_hw_addr
  579. # - fixed the netstat parsing for OpenBSD
  580. # - changed Dot11WEP's key ID field from "key" to "keyid"
  581. #
  582. # Revision 0.9.17.102  2005/06/07 09:54:51  pbi
  583. # - added LEShortEnumField
  584. # - added L2CAP layer
  585. # - added Bluetooth supersocket
  586. # - added srbt() and srbt1()
  587. #
  588. # Revision 0.9.17.101  2005/05/30 17:21:48  pbi
  589. # - Fixes for 0.9.17.100
  590. #
  591. # Revision 0.9.17.100  2005/05/30 17:08:41  pbi
  592. # - added NetBIOS, SMB & Co support (Sebastien Chenevot & Sylvain Sarmejeanne)
  593. #
  594. # Revision 0.9.17.99  2005/05/28 14:28:40  pbi
  595. # - WEP support and ICV computation
  596. #
  597. # Revision 0.9.17.98  2005/05/27 23:05:35  pbi
  598. # -fixed a smlal bug in graphic traceroute
  599. #
  600. # Revision 0.9.17.97  2005/05/27 19:53:04  pbi
  601. # - added WEP ciphering to Dot11WEP
  602. #
  603. # Revision 0.9.17.96  2005/05/25 15:15:10  pbi
  604. # - ability to give a WEP key as an argument to unwep()
  605. #
  606. # Revision 0.9.17.95  2005/05/25 15:05:03  pbi
  607. # - fixed pcap supersockets warnings
  608. #
  609. # Revision 0.9.17.94  2005/05/25 15:01:24  pbi
  610. # - fixed/cleaned ISAKMP
  611. #
  612. # Revision 0.9.17.93  2005/05/25 15:00:34  pbi
  613. # - fixed Packet.remove_underlayer() args
  614. # - fixed FieldLenField
  615. # - added Atheros Prism Header linktype
  616. #
  617. # Revision 0.9.17.92  2005/05/18 16:59:32  pbi
  618. # - some voip_play() stuff
  619. #
  620. # Revision 0.9.17.91  2005/05/18 16:59:01  pbi
  621. # - added BIOCIMMEDIATE option to fix BSD's BPF/pcap/select() behaviour issues
  622. # - made PCAP/DNET the default mode, even for Linux (it seems quicker)
  623. #
  624. # Revision 0.9.17.90  2005/05/18 16:57:07  pbi
  625. # - purge ARP cache when changing IP address of an interface
  626. # - fixed loopback interface detection get_if_raw_hwaddr() for dnet
  627. # - changed a bit Dot11PacketList behaviour
  628. # - fixed build() overload by EAP class
  629. # - fixed close()/recv() mix up in L2pcapListenSocket
  630. #
  631. # Revision 0.9.17.89  2005/05/03 19:18:22  pbi
  632. # - DNET/PCAP stuff reordering
  633. #
  634. # Revision 0.9.17.88  2005/05/03 00:10:12  pbi
  635. # - made Padding not be seen as a payload
  636. #
  637. # Revision 0.9.17.87  2005/04/29 22:37:39  pbi
  638. # - added L2 recognition for L2pcapListenSocket
  639. # - workarround for a bug in libpcap/wrapper?. .next() sometimes returns None
  640. # - added consistant get_if_addr() and get_if_raw_addr()
  641. # - added ifadd(), ifdel() and ifchange() methods to Route class
  642. #
  643. # Revision 0.9.17.86  2005/04/27 21:14:24  pbi
  644. # - small code cleaning
  645. #
  646. # Revision 0.9.17.85  2005/04/27 13:53:32  pbi
  647. # - early BSD port with libdnet and libpcap wrappers
  648. #
  649. # Revision 0.9.17.84  2005/04/24 14:57:45  pbi
  650. # - added a usable geolocation database from GeoIP.
  651. #
  652. # Revision 0.9.17.83  2005/04/24 10:34:57  pbi
  653. # - fixed fragment() (Peter Hardy)
  654. #
  655. # Revision 0.9.17.82  2005/04/23 15:29:21  pbi
  656. # - fixed sndrcv() when given an empty set of packets
  657. #
  658. # Revision 0.9.17.81  2005/04/23 13:55:32  pbi
  659. # - Some Sebek layers fixes (Pierre Lalet)
  660. #
  661. # Revision 0.9.17.80  2005/04/23 13:43:16  pbi
  662. # - Early IrDA support (Pierre Lalet)
  663. #
  664. # Revision 0.9.17.79  2005/04/23 13:42:34  pbi
  665. # - fixed SebekV1 and SebekV2 (Pierre Lalet)
  666. #
  667. # Revision 0.9.17.78  2005/04/23 13:41:33  pbi
  668. # - fixed BitField (Pierre Lalet)
  669. #
  670. # Revision 0.9.17.77  2005/04/23 13:36:15  pbi
  671. # - added threshold for warnings
  672. #
  673. # Revision 0.9.17.76  2005/04/23 11:27:51  pbi
  674. # - Renamed SndRcvAns into SndRcvList
  675. #
  676. # Revision 0.9.17.75  2005/04/23 11:26:12  pbi
  677. # - added color display in srloop()
  678. #
  679. # Revision 0.9.17.74  2005/04/22 13:30:10  pbi
  680. # - fixed dhcp_request()
  681. # - changed make_table semantic : take one lambda instead of 3
  682. # - fixed import_hexcap()
  683. # - fixed StrLenField
  684. # - changed traceroute() and arping() to also return unanswered packets
  685. # - ls() now sorts its output alphabetically
  686. # - LaTeX color theme for straight copy/paste into your doc.
  687. #
  688. # Revision 0.9.17.73  2005/04/15 15:56:08  pbi
  689. # - fixed ARP.answers()' return value
  690. # - made TracerouteResult.graph() use both ASN information source
  691. #
  692. # Revision 0.9.17.72  2005/04/09 22:25:23  pbi
  693. # - fix route.route() to handle extended IP sets (ex. 192.168.*.1-5)
  694. # - generalised statistics in packet lists
  695. # - added Dot11PacketList()
  696. # - added some DHCP options
  697. # - fixes in DHCP options building
  698. # - modified unwep() to decrypt a WEP packet if it was not already done
  699. #
  700. # Revision 0.9.17.71  2005/04/06 10:49:11  pbi
  701. # - forgotten debug msg in Net()
  702. #
  703. # Revision 0.9.17.70  2005/04/04 17:58:15  pbi
  704. # - modified Net() to recognize things like 172.16.*.1-10
  705. #
  706. # Revision 0.9.17.69  2005/04/04 14:24:00  pbi
  707. # - fix DHCP
  708. # - added dhcp_request()
  709. #
  710. # Revision 0.9.17.68  2005/03/28 22:18:04  pbi
  711. # - first attempt with time skew graphing
  712. #
  713. # Revision 0.9.17.67  2005/03/28 22:17:44  pbi
  714. # - use gzip compression for load_object/save_object
  715. # - made RandNum() and Emph() pickable
  716. # - changed prompt color in default color theme
  717. #
  718. # Revision 0.9.17.66  2005/03/28 14:30:01  pbi
  719. # - more DHCP work
  720. #
  721. # Revision 0.9.17.65  2005/03/28 14:29:03  pbi
  722. # - first attempt to generate libnet C code from a packet
  723. #
  724. # Revision 0.9.17.64  2005/03/28 14:28:20  pbi
  725. # - forgot to delete temporary variables in scapy's global scope
  726. #
  727. # Revision 0.9.17.63  2005/03/28 14:22:38  pbi
  728. # - added colors, color themes, colored prompt
  729. #
  730. # Revision 0.9.17.62  2005/03/24 16:19:33  pbi
  731. # - made it possible to use a PacketList as a parameter for send* or sr*
  732. #
  733. # Revision 0.9.17.61  2005/03/23 18:27:06  pbi
  734. # - used init_cookie for ISAKMP.answers()
  735. # - raised an exception in route.make_route if parameters are incomplete
  736. #
  737. # Revision 0.9.17.60  2005/03/23 17:07:56  pbi
  738. # - fixed session loading with -s
  739. # - prevented save_session() to trash current session
  740. # - changed AnsweringMachine to make send_reply() a bit more generic
  741. #
  742. # Revision 0.9.17.59  2005/03/22 16:52:44  pbi
  743. # - added _elt2show() to PacketList
  744. # - changed PacketList.show() to use _elt2show()
  745. #
  746. # Revision 0.9.17.58  2005/03/22 16:21:39  pbi
  747. # - added conversation() to PacketList
  748. # - added padding() to PacketList
  749. # - fixed StrNullField
  750. # - added haslayer_str() to Packet
  751. # - changed Packet.sprintf() to use haslayer_str
  752. # - changed answers() to ask payload if same class as other
  753. # - add count parameter to rdpcap
  754. #
  755. # Revision 0.9.17.57  2005/03/16 14:18:28  pbi
  756. # - added StrNullField
  757. #
  758. # Revision 0.9.17.56  2005/03/14 18:14:28  pbi
  759. # - LLNumTypes fix
  760. # - Added linktype recognition to PcapWriter class
  761. #
  762. # Revision 0.9.17.55  2005/03/14 17:59:23  pbi
  763. # - indentation cosmetic fix
  764. #
  765. # Revision 0.9.17.54  2005/03/14 17:53:56  pbi
  766. # - wrpcap() now writes the correct linktype in the pcap file
  767. #
  768. # Revision 0.9.17.53  2005/03/14 17:22:23  pbi
  769. # - added ISAKMP transforms decoding
  770. #
  771. # Revision 0.9.17.52  2005/03/14 16:40:58  pbi
  772. # - added ikescan()
  773. # - added ISAKMPTransformField
  774. # - fixed PacketList's private methods names do begin only with one "_"
  775. #
  776. # Revision 0.9.17.51  2005/03/14 13:03:11  pbi
  777. # - added a prn parameter to PacketList's summary() and nsummary()
  778. #
  779. # Revision 0.9.17.50  2005/03/14 12:56:24  pbi
  780. # - make internal methods of PacketResult begins with __
  781. #
  782. # Revision 0.9.17.49  2005/03/14 12:52:41  pbi
  783. # - Deprecated display() method (for all objects). Use show() instead.
  784. #
  785. # Revision 0.9.17.48  2005/03/14 12:48:29  pbi
  786. # - Modified PacketField to stop at Padding instead of Raw
  787. # - Added PacketLenField
  788. # - More ISAKMP rework. Almost working.
  789. #
  790. # Revision 0.9.17.47  2005/03/14 10:20:49  pbi
  791. # - added unwep() method to Dot11 packets
  792. # - fixed 4 missing bytes in Dot11WEP
  793. #
  794. # Revision 0.9.17.46  2005/03/08 17:56:49  pbi
  795. # - added a possibility to give a hint for srp() to choose the intended interface
  796. # - added is_promisc() to find boxes in promisc mode (will not always work) (Javier Merino)
  797. #
  798. # Revision 0.9.17.45  2005/03/08 17:21:14  pbi
  799. # - added PacketField
  800. # - ISAKMP work
  801. #
  802. # Revision 0.9.17.44  2005/03/06 17:50:06  pbi
  803. # - changed PCAP and DNET defaults
  804. #
  805. # Revision 0.9.17.43  2005/03/03 17:15:26  pbi
  806. # - ISAKMP work
  807. #
  808. # Revision 0.9.17.42  2005/03/02 18:09:00  pbi
  809. # - added make_world_trace() method to TracerouteResult for a xtraceroute-like
  810. #
  811. # Revision 0.9.17.41  2005/02/20 22:33:55  pbi
  812. # - Sebek protocol definitions enhancements (Pierre Lalet)
  813. #
  814. # Revision 0.9.17.40  2005/02/20 22:31:49  pbi
  815. # - added ARP answering machine (farpd) (Pierre Lalet)
  816. #
  817. # Revision 0.9.17.39  2005/02/20 22:22:23  pbi
  818. # - Graphic traceroute enhanced to cope with TCP, UDP, ICMP or other traceroutes
  819. # - ASN clustering in graphic traceroute can be controlled with the "ASN" parameter
  820. #
  821. # Revision 0.9.17.38  2005/02/18 21:03:26  pbi
  822. # - MGCP  early support
  823. # - RandString()
  824. #
  825. # Revision 0.9.17.37  2005/02/10 22:33:13  pbi
  826. # - export_object()/import_object() to copy/paste base64 gzipped pickled objects
  827. # - prevent save_session from deleting unpicklable objects
  828. # - added hexdump() and hexraw() methods to PacketList object
  829. # - Raw packet answers any Raw packet
  830. # - added conf.checkIPaddr to recognize broadcast replies (BOOTP/DHCP)
  831. #
  832. # Revision 0.9.17.36  2005/02/02 22:39:48  pbi
  833. # - added GPRS dummy packet class
  834. #
  835. # Revision 0.9.17.35  2005/01/29 00:29:25  pbi
  836. # - added l4 parameter to traceroute() for UDP, ICMP and other layer 4 traceroutes
  837. # - tweaked TracerouteResult display()
  838. #
  839. # Revision 0.9.17.34  2005/01/26 23:43:19  pbi
  840. # - removed some outdated functions
  841. #
  842. # Revision 0.9.17.33  2005/01/26 23:41:58  pbi
  843. # - small simplification of TracerouteResult display() thanks to new sprintf()
  844. #   conditionnal statement
  845. #
  846. # Revision 0.9.17.32  2005/01/26 23:12:59  pbi
  847. # - added conditionnal statements in format strings
  848. #
  849. # Revision 0.9.17.31  2005/01/26 22:30:36  pbi
  850. # - removed an uneeded "else" in  sprintf()
  851. #
  852. # Revision 0.9.17.30  2005/01/22 22:25:24  pbi
  853. # - re-added node coloring lost code line in traceroute graphing code
  854. #
  855. # Revision 0.9.17.29  2005/01/22 21:48:55  pbi
  856. # - fixed need for warning() before it was declared
  857. #
  858. # Revision 0.9.17.28  2005/01/22 21:47:11  pbi
  859. # - added ARPingResult to handle arping() results
  860. # - moved ARPing displaying logic to ARPing object
  861. #
  862. # Revision 0.9.17.27  2005/01/22 21:42:59  pbi
  863. # - added args todo_graph()
  864. # - added TracerouteResults object to handle traceroute results
  865. # - moved traceroute displaying logic to TracerouteResult object
  866. # - moved traceroute graphing logic to TracerouteResult object
  867. #
  868. # Revision 0.9.17.26  2005/01/20 22:59:07  pbi
  869. # - graph_traceroute : added AS clustering, colors, tweaks
  870. #
  871. # Revision 0.9.17.25  2005/01/17 22:10:58  pbi
  872. # - added do_graph() to draw GraphViz graphs using SVG output, displayed with ImageMagick
  873. # - added graph_traceroute() to make a graph from multiple traceroutes
  874. # - added timeout parameter to traceroute()
  875. #
  876. # Revision 0.9.17.24  2005/01/13 14:25:00  pbi
  877. # - added Sebek v1 and v2 protocols (Pierre Lalet)
  878. #
  879. # Revision 0.9.17.23  2005/01/10 21:55:14  pbi
  880. # - addded promisc and iface parameters to L3RawSocket
  881. #
  882. # Revision 0.9.17.22  2004/12/26 18:07:43  pbi
  883. # - Improved PacketList with stability by addition and slicing
  884. # - Added plot() to PacketList using Gnuplot
  885. # - Added StrStopField
  886. # - Added conf.debug_disssector to prevent dissector's exception from being catched
  887. # - Added CookedLinux packet type
  888. # - Show linktype number when it is unknown
  889. #
  890. # Revision 0.9.17.21  2004/12/26 16:04:57  pbi
  891. # - removed strace in soxmix command line
  892. # - DHCP support (from Mattias Wadman)
  893. # - added missing make_table to PacketList class
  894. # - have UDP class asks its payload for answers()
  895. #
  896. # Revision 0.9.17.20  2004/12/01 17:13:28  pbi
  897. # - Early WEP support
  898. # - voip_play() tweaks
  899. # - Added LEShortField for Dot11 SC field
  900. #
  901. # Revision 0.9.17.19  2004/10/18 13:42:50  pbi
  902. # - HSRP early support
  903. # - Cisco CSSP Skinny early support
  904. # - added Little Endian IntEnumField
  905. # - added filter() method to PacketList
  906. # - some voip_play() work
  907. # - loop parameter value in send*() is used as the time to sleep between 2 loops
  908. #
  909. # Revision 0.9.17.18  2004/09/21 21:45:20  pbi
  910. # - added recv() method to PcapReader to emulate a SuperSocket
  911. # - added "offline" parameter to sniff() to use sniff on pcap files
  912. # - removed voip_play_offline() and renamed voip_play_sniff() to voip_play()
  913. #   which is now available to play offline
  914. #
  915. # Revision 0.9.17.17  2004/09/21 21:32:41  pbi
  916. # - added early PPPoE support (Ralf Ertzinger)
  917. # - fixed DNS summary() to handle empty queries or answers
  918. #
  919. # Revision 0.9.17.16  2004/09/21 14:58:15  pbi
  920. # - added VOIP playing functions (not tested)
  921. #
  922. # Revision 0.9.17.15  2004/09/17 22:00:47  pbi
  923. # - transfert traceroute() and arping() options to sndrcv() ("retry", etc.)
  924. # - fixed retry option in sndrcv()
  925. # - tweaked AnweringMachine class
  926. # - rewrited airpwn to use AnsweringMachine
  927. #
  928. # Revision 0.9.17.14  2004/09/13 16:57:01  pbi
  929. # - added loopback routing
  930. #
  931. # Revision 0.9.17.13  2004/09/12 21:44:45  pbi
  932. # - AnsweringMachine working as I wanted!
  933. #
  934. # Revision 0.9.17.12  2004/09/10 16:54:46  pbi
  935. # - AnsweringMachine twaking
  936. # - added DNS spoofing answering machine
  937. #
  938. # Revision 0.9.17.11  2004/09/08 13:42:38  pbi
  939. # - renamed  ScapyPcapWriter class to PcapWriter
  940. # - added linktype parameter to PcapWriter (William McVey)
  941. # - added PcapReader class (William McVey)
  942. #
  943. # Revision 0.9.17.10  2004/09/08 13:06:01  pbi
  944. # - added some text correspondances to Radius code field
  945. #
  946. # Revision 0.9.17.9  2004/09/06 14:28:02  pbi
  947. # - early radius support
  948. #
  949. # Revision 0.9.17.8  2004/09/06 14:17:11  pbi
  950. # - added "store" parameter to sniff()
  951. # - added AnsweringMachine class to handle request/response protocols
  952. # - replaced bootpd by a AnsweringMachine subclass
  953. # - created DHCP answering machine draft
  954. #
  955. # Revision 0.9.17.7  2004/09/03 22:11:35  pbi
  956. # - finished airpwn()
  957. #
  958. # Revision 0.9.17.6  2004/08/13 16:49:51  pbi
  959. # - added first version of airpwn() clone
  960. #
  961. # Revision 0.9.17.5  2004/08/11 15:25:08  pbi
  962. # - added RIP protocol
  963. #
  964. # Revision 0.9.17.4  2004/08/09 14:00:20  pbi
  965. # - added gzip support to sessions saving
  966. # - can force pickle protocol to inferior values for pickle backward compatility
  967. #
  968. # Revision 0.9.17.3  2004/08/07 10:59:34  pbi
  969. # - fixed self reloading when launched from a different directory
  970. # - fixed session reloading problems with PacketList() and SndRcvAns()
  971. # - added load_session(), save_session(), update_session()
  972. #
  973. # Revision 0.9.17.2  2004/07/28 21:16:12  pbi
  974. # - added nsummary() method to SndRcvList() class
  975. #
  976. # Revision 0.9.17.1  2004/07/26 19:52:55  pbi
  977. # Release 0.9.17
  978. #
  979. # Revision 0.9.16.18  2004/07/26 19:50:16  pbi
  980. # - added ScapyPcapWriter class (William McVey)
  981. #
  982. # Revision 0.9.16.17  2004/07/26 19:24:48  pbi
  983. # - do not need to be named 'scapy.py' anymore
  984. # - use of PacketList() for rdpcap() and sniff()
  985. # - fixed a bug in StrFixedLenField
  986. # - early IKE and ISAKMP support
  987. #
  988. # Revision 0.9.16.16  2004/07/16 15:39:37  pbi
  989. # - small fix on bootpd
  990. #
  991. # Revision 0.9.16.15  2004/07/10 13:13:25  pbi
  992. # - finished testing ethertype in supersockets to decide wether or not to apply BPF filters
  993. #
  994. # Revision 0.9.16.14  2004/07/10 13:06:38  pbi
  995. # - do not apply any BPF filter if ethertype is given to a supersocket (so that ARP requests will work
  996. #   whatever the conf.except_filter value is)
  997. #
  998. # Revision 0.9.16.13  2004/07/09 09:11:15  pbi
  999. # - changed the header and blocked the licence to GPLv2 only
  1000. #
  1001. # Revision 0.9.16.12  2004/07/09 09:07:41  pbi
  1002. # - added an independant routing table (conf.route) and methods to manipulate it
  1003. # - tweaked results stats
  1004. #
  1005. # Revision 0.9.16.11  2004/07/05 22:43:49  pbi
  1006. # - wrapper classes for results presentations and manipulation
  1007. # - sndrcv() retry auto adjustment when giving a negative value
  1008. #
  1009. # Revision 0.9.16.10  2004/07/05 08:53:41  pbi
  1010. # - added retry option to sndrcv()
  1011. # - improved debug class
  1012. # - added ottl() and hops() methods for IPTools class
  1013. # - improved UDP and ICMP summary()
  1014. #
  1015. # Revision 0.9.16.9  2004/06/07 16:09:21  pbi
  1016. # - fix again TCP.answers() and TCPerror.answers()
  1017. #
  1018. # Revision 0.9.16.8  2004/06/07 16:06:27  pbi
  1019. # - fixed conf.checkIPsrc behaviour of answers() and hashret() for TCP/UDP/TCPerror/UDPerror
  1020. # - added conf.debug_match to keep track of unanswered packets in debug.sent and debug.recv
  1021. #
  1022. # Revision 0.9.16.7  2004/06/07 09:20:43  pbi
  1023. # - added LEIntField and StrFixedLenField
  1024. # - added partial PrismHeader support
  1025. #
  1026. # Revision 0.9.16.6  2004/04/29 15:46:19  pbi
  1027. # - fixed fragment()
  1028. #
  1029. # Revision 0.9.16.5  2004/03/31 09:24:43  pbi
  1030. # - fix nmap fingerprint db parsing to handle the new format (Jochen Bartl)
  1031. #
  1032. # Revision 0.9.16.4  2004/03/23 08:45:10  pbi
  1033. # - Support for reading big endian pcap files (Pekka Pietikainen)
  1034. #
  1035. # Revision 0.9.16.3  2004/02/28 11:12:12  pbi
  1036. # - got rid of some future warnings (N. Bareil <nbareil@mouarf.org>)
  1037. # - improved BitField() for arbitrary length bit fields (N. Bareil <nbareil@mouarf.org>)
  1038. # - NTP protocol (N. Bareil <nbareil@mouarf.org>)
  1039. #
  1040. # Revision 0.9.16.2  2004/02/22 17:49:51  pbi
  1041. # added first sketch of a bootp daemon: bootpd()
  1042. #
  1043. # Revision 0.9.16.1  2004/01/26 18:01:00  pbi
  1044. # Release 0.9.16
  1045. #
  1046. # Revision 0.9.15.15  2004/01/26 18:00:08  pbi
  1047. # - added more text for DNS codes
  1048. #
  1049. # Revision 0.9.15.14  2004/01/15 13:24:48  pbi
  1050. # - fixed the case where IP field is a list of nets
  1051. # - randomize IPID in traceroute() to work better with conf.checkIPsrc=0
  1052. # - added make_tex_table() and make_lined_table()
  1053. # - added IPID_count() to identify machines with their IPID
  1054. # - added sport and dport args to fragleak()
  1055. #
  1056. # Revision 0.9.15.13  2004/01/11 11:47:07  pbi
  1057. # - srploop() and srloop() improvements
  1058. #
  1059. # Revision 0.9.15.12  2004/01/11 01:28:21  pbi
  1060. # - srloop() and srploop() improvements
  1061. #
  1062. # Revision 0.9.15.11  2004/01/11 01:07:05  pbi
  1063. # - srloop() and srploop() improvements
  1064. #
  1065. # Revision 0.9.15.10  2004/01/10 23:42:58  pbi
  1066. # - added srloop() and srploop() functions
  1067. #
  1068. # Revision 0.9.15.9  2004/01/10 23:40:51  pbi
  1069. # - added
  1070. #
  1071. # Revision 0.9.15.8  2004/01/09 16:42:42  pbi
  1072. # - improved send() and sendp() with parameters loop and verbose
  1073. #
  1074. # Revision 0.9.15.7  2004/01/09 16:04:07  pbi
  1075. # - fixed ARP opcodes values
  1076. #
  1077. # Revision 0.9.15.6  2004/01/09 15:53:46  pbi
  1078. # - added RARP and IARP req/resp description in ARP operation Enum field
  1079. #
  1080. # Revision 0.9.15.5  2003/12/19 15:54:30  pbi
  1081. # - added checkIPID and checkIPsrc options in conf to recognize IP in ICMP errors from broken IP stacks (see conf.__doc__)
  1082. # - changed default TCP source port to 20 (Muahahahah!)
  1083. # - tweaked TCP summary
  1084. # - changed default UDP source and destination ports to 53
  1085. # - created import_hexcap() to copy-paste an hexcap from tcpdump -xX, and get a string to feed IP() or ARP() or whatever
  1086. # - created make_table() to present results in a table from a list, and functions that map the list to x,y and z=f(x,y).
  1087. #
  1088. # Revision 0.9.15.4  2003/10/30 16:11:41  pbi
  1089. # - little enhancements to the DNS packets
  1090. # - added dyndns_add() and dyndns_del() (rfc2136)
  1091. # - fixed a format string error (3 times)
  1092. #
  1093. # Revision 0.9.15.3  2003/10/16 10:41:42  biondi
  1094. # - redesign summary() method
  1095. # - fixed Dot11 addresses fields
  1096. #
  1097. # Revision 0.9.15.2  2003/10/15 14:41:09  biondi
  1098. # - caching format size (calcsize()) in Field main class
  1099. # - allow first packet desassembly to fail in SuperSockets, falling back to Raw
  1100. #
  1101. # Revision 0.9.15.1  2003/10/02 15:24:29  pbi
  1102. # Release 0.9.15
  1103. #
  1104. # Revision 0.9.14.8  2003/10/02 15:16:26  pbi
  1105. # - small fix for p0f_base
  1106. # - lazy loading for p0f, queso and nmap knowledge databases
  1107. #
  1108. # Revision 0.9.14.7  2003/10/02 14:14:17  pbi
  1109. # - added a LongField
  1110. # - added classes and bonds for 802.11
  1111. # - added error handling and magic checks for rdpcap()
  1112. #
  1113. # Revision 0.9.14.6  2003/09/12 14:45:35  pbi
  1114. # - had Dot11 working
  1115. #
  1116. # Revision 0.9.14.5  2003/09/12 10:04:05  pbi
  1117. # - added summary() method to Packet objects
  1118. #
  1119. # Revision 0.9.14.4  2003/09/12 09:28:28  pbi
  1120. # - added SNAP protocol
  1121. # - catched broken pipe exception when shild die in sndrcv()
  1122. # - fixed default L2socket type in srp() and srp1() (ETH_P_ALL)
  1123. # - fixed format string in attach_filter()
  1124. #
  1125. # Revision 0.9.14.3  2003/09/10 08:47:41  pbi
  1126. # - fixed the fact that bpf filters were generated in cooked mode, and thus did
  1127. #   not work
  1128. # - filter on socket type ETH_P_ARP instead of using a bpf filter for ARP replies
  1129. # - fixed the way of handling the SuperSocket close.
  1130. # - uniformised the naming for interface parameter : iface instead of iff
  1131. # - fixed the FutureWarning for long integers
  1132. # - fixed a typo in 3 format strings (%*i instead of %i)
  1133. #
  1134. # Revision 0.9.14.2  2003/07/20 00:12:04  pbi
  1135. # -added "-i any" for tcpdump to compile filters even if they don't work on main interface
  1136. # - put PPP special case before layer 2 general case in a super socket
  1137. # - added th filter parameter to L3RawSocket
  1138. # - added a special case in getmacbyip() when loopback interface is concernet
  1139. # - added value for RAWIP linktype in pcap capture files
  1140. #
  1141. # Revision 0.9.14.1  2003/06/25 13:18:23  pbi
  1142. # Release 0.9.14, from 0.9.13.4
  1143. #
  1144. # Revision 0.9.13.4  2003/06/25 12:35:57  pbi
  1145. # - fixed a regression in L3PacketSocket for ppp links
  1146. #
  1147. # Revision 0.9.13.3  2003/05/31 14:01:12  biondi
  1148. # - more tweaks on Packet.sprintf(). Added __doc__.
  1149. #
  1150. # Revision 0.9.13.2  2003/05/31 13:17:42  biondi
  1151. # - small tweaks in Packet.sprintf()
  1152. #
  1153. # Revision 0.9.13.1  2003/05/16 13:34:30  pbi
  1154. # Release 0.9.13
  1155. #
  1156. # Revision 0.9.12.9  2003/05/16 13:32:38  pbi
  1157. # - fixed verbose parameter in nmap_fp()
  1158. #
  1159. # Revision 0.9.12.8  2003/05/16 13:28:49  pbi
  1160. # - small enhancements in self-documentation
  1161. # - added early experiemental support for BOOTP and 802.11
  1162. #
  1163. # Revision 0.9.12.7  2003/05/16 11:25:48  pbi
  1164. # - added workarroung python bug 643005 (socket.inet_aton("255.255.255.255"))
  1165. # - use answers() method instead of operator
  1166. # - added hashret() method : returns a hash that is invariant for a packet and its reply
  1167. # - use hashret() in sndrcv() for dramatic improvements for matching replies on big set of packets
  1168. # - change report_ports() to return a string instead of printing
  1169. #
  1170. # Revision 0.9.12.6  2003/05/16 09:28:40  pbi
  1171. # - improved the __repr__() method of Packet class
  1172. #
  1173. # Revision 0.9.12.5  2003/05/12 15:15:02  pbi
  1174. # - added minttl parameter to traceroute()
  1175. #
  1176. # Revision 0.9.12.4  2003/05/06 13:39:21  pbi
  1177. # - Improved random number object (thanks to O. Poyen)
  1178. #
  1179. # Revision 0.9.12.3  2003/05/06 10:45:27  pbi
  1180. # - fixed a name overlap on "type" in L2ListenSocket and L3PacketSocket (thanks to E. M. Hopper)
  1181. #
  1182. # Revision 0.9.12.2  2003/05/06 10:41:58  pbi
  1183. # - externalized conversion from probes to signature with nmap_probes2sig() use probe results from, say, a pcap file
  1184. #
  1185. # Revision 0.9.12.1  2003/04/27 10:07:30  pbi
  1186. # Release 0.9.12
  1187. #
  1188. # Revision 0.9.11.5  2003/04/27 10:04:03  pbi
  1189. # - Fixed long int conversion in attach_filter()
  1190. #
  1191. # Revision 0.9.11.4  2003/04/27 10:00:57  pbi
  1192. # - rectification in SetGen to unroll Gen instances in lists
  1193. # - Completed DNS types and qtypes names
  1194. # - Small tuning in nmap_match_one_sig()
  1195. # - Parallelized nmap_sig()
  1196. #
  1197. # Revision 0.9.11.3  2003/04/24 12:47:49  pbi
  1198. # - removed 4 byte IP string autorecognition. Never used and broken for 4 byte names
  1199. # - added "islist" flag to fields to distinguish a list value from a list of values
  1200. # - changed TCP options from dict to list to preserve order and redundancy
  1201. # - added conf.except_filter, to have every command ignore your own traffic (BPF filter)
  1202. # - worked in progress for nmap OS fingerprint. Added PU test. Fixed other tests.
  1203. # - added nmap_sig2txt() to transform a signature to its text form, suitable for nmap base
  1204. #
  1205. # Revision 0.9.11.2  2003/04/23 21:23:30  pbi
  1206. # - small fixes in init_queso()
  1207. # - experimental support of nmap fingerprinting (not complete yet)
  1208. #
  1209. # Revision 0.9.11.1  2003/04/22 14:38:16  pbi
  1210. # Release 0.9.11
  1211. #
  1212. # Revision 0.9.10.8  2003/04/22 14:37:32  pbi
  1213. # - fixed bug in getmacbyip() using dnet module
  1214. # - deactivated getmacbyip() using dnet module because it did not resolve unknown IPs
  1215. # - added some commands listed by lsc()
  1216. #
  1217. # Revision 0.9.10.7  2003/04/22 13:55:01  pbi
  1218. # - some getattr/setattr/delattr enhancements
  1219. #
  1220. # Revision 0.9.10.6  2003/04/22 13:52:00  pbi
  1221. # - added experimental support for QueSO OS fingerprinting. Has someone a *recent* database ?
  1222. #
  1223. # Revision 0.9.10.5  2003/04/18 17:45:15  pbi
  1224. # - improved the completer to complete with protocol fields
  1225. # - small fix in get_working_if()
  1226. #
  1227. # Revision 0.9.10.4  2003/04/16 14:53:36  pbi
  1228. # - added option to include padding or not
  1229. #
  1230. # Revision 0.9.10.3  2003/04/16 14:35:32  pbi
  1231. # - added L2dnetSocket()
  1232. # - improved arping()
  1233. #
  1234. # Revision 0.9.10.2  2003/04/16 12:40:40  pbi
  1235. # - fixed the case when the history file does not exist
  1236. #
  1237. # Revision 0.9.10.1  2003/04/14 15:43:45  pbi
  1238. # Release 0.9.10
  1239. #
  1240. # Revision 0.9.9.15  2003/04/14 15:42:47  pbi
  1241. # - added L3pcapListenSocket
  1242. # - fixed L3ListenSocket to use ETH_P_ALL instead of ETH_P_IP by default
  1243. #
  1244. # Revision 0.9.9.14  2003/04/14 14:57:53  pbi
  1245. # - reworked L3dnetSocket
  1246. #
  1247. # Revision 0.9.9.13  2003/04/14 13:53:28  pbi
  1248. # - added completion (rlcompleter) and history support
  1249. #
  1250. # Revision 0.9.9.12  2003/04/14 10:05:42  pbi
  1251. # - bugfixed the close() method of some supersockets
  1252. #
  1253. # Revision 0.9.9.11  2003/04/13 21:41:01  biondi
  1254. # - added get_working_if()
  1255. # - use get_working_if() for default interface
  1256. #
  1257. # Revision 0.9.9.10  2003/04/12 23:33:42  biondi
  1258. # - add DNS layer (do not compress when assemble, answers() is missing)
  1259. #
  1260. # Revision 0.9.9.9  2003/04/12 22:15:40  biondi
  1261. # - added EnumField
  1262. # - used EnumField for ARP(), ICMP(), IP(), EAPOL(), EAP(),...
  1263. #
  1264. # Revision 0.9.9.8  2003/04/11 16:52:29  pbi
  1265. # - better integration of libpcap and libdnet, if available
  1266. #
  1267. # Revision 0.9.9.7  2003/04/11 15:49:31  pbi
  1268. # - some tweaks about supersockets close() and __del__() (not satisfied)
  1269. # - added L3dnetSocket, that use libdnet and libpcap if available
  1270. #
  1271. # Revision 0.9.9.6  2003/04/11 13:46:49  pbi
  1272. # - fixed a regression in bitfield dissection
  1273. # - tweaked and fixed a lot of small things arround supersockets
  1274. #
  1275. # Revision 0.9.9.5  2003/04/10 14:50:22  pbi
  1276. # - clean session only if it is to be saved
  1277. # - forgot to give its name to Padding class
  1278. # - fixed the NoPayload comparison tests so that they work on reloaded sessions
  1279. #
  1280. # Revision 0.9.9.4  2003/04/10 13:45:22  pbi
  1281. # - Prepared the configuration of L2/L3 supersockets
  1282. #
  1283. # Revision 0.9.9.3  2003/04/08 18:34:48  pbi
  1284. # - little fix in L2ListenSocket.__del__()
  1285. # - added doc and options in Conf class
  1286. # - added promisc support for L3PacketSocket, so that you can get answers to spoofed packets
  1287. #
  1288. # Revision 0.9.9.2  2003/04/08 17:42:19  pbi
  1289. # - added extract_padding() method to UDP
  1290. #
  1291. # Revision 0.9.9.1  2003/04/08 17:23:33  pbi
  1292. # Release 0.9.9
  1293. #
  1294. # Revision 0.9.8.9  2003/04/08 17:22:25  pbi
  1295. # - use cPickle instead of pickle (quicker and works with __getattr__() recursion)
  1296. # - small fixes on send() and sendp()
  1297. #
  1298. # Revision 0.9.8.8  2003/04/08 16:48:04  pbi
  1299. # - EAPOL overload Ether dst with PAE_GROUP_ADDR
  1300. # - tuning in ports_report()
  1301. # - tuning in fragleak
  1302. #
  1303. # Revision 0.9.8.7  2003/04/07 15:32:10  pbi
  1304. # - uses /usr/bin/env invocation
  1305. #
  1306. # Revision 0.9.8.6  2003/04/07 14:57:12  pbi
  1307. # - catch error during payload dissection and consider payload as raw data
  1308. #
  1309. # Revision 0.9.8.5  2003/04/07 14:43:13  pbi
  1310. # - srp() becomes srp1() and sr() equivalent for L2 is called srp()
  1311. # - hastype() Packet methods renamed to haslayer()
  1312. # - added getlayer() Packet method
  1313. # - added padding detection for layers that have a length field
  1314. # - added fragment() that fragment an IP packet
  1315. # - added report_ports() to scan a machine and output LaTeX report
  1316. #
  1317. # Revision 0.9.8.4  2003/04/01 11:19:06  pbi
  1318. # - added FlagsField(), used for TCP and IP
  1319. # - rfc3514 compliance
  1320. #
  1321. # Revision 0.9.8.3  2003/03/28 14:55:18  pbi
  1322. # Added pkt2uptime() : uses TCP timestamp to predict when the machine was booted
  1323. #
  1324. # Revision 0.9.8.2  2003/03/27 15:58:54  pbi
  1325. # - fixed sprintf() regression to use attributes from a packet that are not fields (eg: payload)
  1326. #
  1327. # Revision 0.9.8.1  2003/03/27 15:43:20  pbi
  1328. # Release 0.9.8
  1329. #
  1330. # Revision 0.9.7.9  2003/03/27 15:07:42  pbi
  1331. # - add filter support for sr(), sr1() and srp()
  1332. # - use filters for getmacbyip() and traceroute() for better reliability under heavy load
  1333. #
  1334. # Revision 0.9.7.8  2003/03/27 14:45:11  pbi
  1335. # - better timeout management in sndrcv
  1336. # - bugfixed sys.exit() imbrication issues
  1337. # - some self documentation
  1338. # - added lsc()command
  1339. #
  1340. # Revision 0.9.7.7  2003/03/26 17:51:33  pbi
  1341. # - Added IPTool class, to add commands like whois() to IP layer.
  1342. # - Have unknown class attributes be asked to payload before raising an exception.
  1343. #
  1344. # Revision 0.9.7.6  2003/03/26 17:35:36  pbi
  1345. # More powerful sprintf format string : %[fmt[r],][cls[:nb].]field% where fmt is a classic one, r can be
  1346. # appended for raw substitution (ex: IP.flags=0x18 instead of SA), nb is the number of the layer we want
  1347. # (ex: for IP/IP packets, IP:2.src is the src of the upper IP layer). Special case : "%.time" is the creation time.
  1348. # Ex : p.sprintf("%.time% %-15s,IP.src% -> %-15s,IP.dst% %IP.chksum% %03xr,IP.proto% %r,TCP.flags%")
  1349. #
  1350. # Revision 0.9.7.5  2003/03/26 14:47:39  pbi
  1351. # Added creation time packet. Supported by read/write pcap.
  1352. #
  1353. # Revision 0.9.7.4  2003/03/26 14:25:09  pbi
  1354. # Added the NoPayload terminal class
  1355. #
  1356. # Revision 0.9.7.3  2003/03/26 13:31:11  pbi
  1357. # Fixed RCS Id
  1358. #
  1359. # Revision 0.9.7.2  2003/03/26 13:30:05  pbi
  1360. # Adding RCS Id
  1361. #
  1362. #
  1363.  
  1364.  
  1365. from __future__ import generators
  1366.  
  1367. RCSID="$Id: scapy.py,v 1.0.4.1 2006/03/17 12:48:28 pbi Exp $"
  1368.  
  1369. VERSION = RCSID.split()[2]+"beta"
  1370.  
  1371.  
  1372. def usage():
  1373.     print "Usage: scapy.py [-s sessionfile]"
  1374.     sys.exit(0)
  1375.  
  1376.  
  1377. ##########[XXX]#=--
  1378. ##
  1379. #   Next things to do :
  1380. #
  1381. #  - fields to manage variable length hw addr (ARP, BOOTP, etc.)
  1382. #  - improve pcap capture file support
  1383. #  - better self-doc
  1384. #
  1385. ##
  1386. ##########[XXX]#=--
  1387.  
  1388.  
  1389. #############################
  1390. ##### Logging subsystem #####
  1391. #############################
  1392.  
  1393. import logging,traceback,time
  1394.  
  1395. class ScapyFreqFilter(logging.Filter):
  1396.     def __init__(self):
  1397.         logging.Filter.__init__(self)
  1398.         self.warning_table = {}
  1399.     def filter(self, record):        
  1400.         wt = conf.warning_threshold
  1401.         if wt > 0:
  1402.             stk = traceback.extract_stack(limit=1)
  1403.             caller = stk[0][1]
  1404.             tm,nb = self.warning_table.get(caller, (0,0))
  1405.             ltm = time.time()
  1406.             if ltm-tm > wt:
  1407.                 tm = ltm
  1408.                 nb = 0
  1409.             else:
  1410.                 if nb < 2:
  1411.                     nb += 1
  1412.                     if nb == 2:
  1413.                         record.msg = "more "+record.msg
  1414.                 else:
  1415.                     return 0
  1416.             self.warning_table[caller] = (tm,nb)
  1417.         return 1    
  1418.  
  1419. log_scapy = logging.getLogger("scapy")
  1420. console_handler = logging.StreamHandler()
  1421. console_handler.setFormatter(logging.Formatter("%(levelname)s: %(message)s"))
  1422. log_scapy.addHandler(console_handler)
  1423. log_runtime = logging.getLogger("scapy.runtime")          # logs at runtime
  1424. log_runtime.addFilter(ScapyFreqFilter())
  1425. log_interactive = logging.getLogger("scapy.interactive")  # logs in interactive functions
  1426. log_loading = logging.getLogger("scapy.loading")          # logs when loading scapy
  1427.  
  1428. if __name__ == "__main__":
  1429.     log_scapy.setLevel(1)
  1430.  
  1431.  
  1432. ##################
  1433. ##### Module #####
  1434. ##################
  1435.  
  1436. import socket, sys, getopt, string, struct, random, os, code
  1437. import cPickle, copy, types, gzip, base64, re
  1438. from select import select
  1439. from fcntl import ioctl
  1440. import fcntl
  1441.  
  1442.  
  1443. try:
  1444.     import Gnuplot
  1445.     GNUPLOT=1
  1446. except ImportError:
  1447.     log_loading.info("did not find python gnuplot wrapper . Won't be able to plot")
  1448.     GNUPLOT=0
  1449.  
  1450. try:
  1451.     import pyx
  1452.     PYX=1
  1453. except ImportError:
  1454.     log_loading.info("Can't import PyX. Won't be able to use psdump() or pdfdump()")
  1455.     PYX=0
  1456.  
  1457.  
  1458. LINUX=sys.platform.startswith("linux")
  1459. OPENBSD=sys.platform.startswith("openbsd")
  1460. FREEBSD=sys.platform.startswith("freebsd")
  1461. DARWIN=sys.platform.startswith("darwin")
  1462. BIG_ENDIAN= struct.pack("H",1) == "\x00\x01"
  1463. X86_64 = (os.uname()[4] == 'x86_64')
  1464. SOLARIS=sys.platform.startswith("sunos")
  1465.  
  1466.  
  1467. if LINUX:
  1468.     DNET=PCAP=0
  1469. else:
  1470.     DNET=PCAP=1
  1471.     
  1472.  
  1473. if PCAP:
  1474.     try:
  1475.         import pcap
  1476.         PCAP = 1
  1477.     except ImportError:
  1478.         if LINUX:
  1479.             log_loading.warning("did not find pcap module. Fallback to linux primitives")
  1480.             PCAP = 0
  1481.         else:
  1482.             if __name__ == "__main__":
  1483.                 log_loading.error("did not find pcap module")
  1484.                 raise SystemExit
  1485.             else:
  1486.                 raise
  1487.  
  1488. if DNET:
  1489.     try:
  1490.         import dnet
  1491.         DNET = 1
  1492.     except ImportError:
  1493.         if LINUX:
  1494.             log_loading.warning("did not find dnet module. Fallback to linux primitives")
  1495.             DNET = 0
  1496.         else:
  1497.             if __name__ == "__main__":
  1498.                 log_loading.error("did not find dnet module")
  1499.                 raise SystemExit
  1500.             else:
  1501.                 raise
  1502.  
  1503. if not PCAP:
  1504.     f = os.popen("tcpdump -V 2> /dev/null")
  1505.     if f.close() >> 8 == 0x7f:
  1506.         log_loading.warning("Failed to execute tcpdump. Check it is installed and in the PATH")
  1507.         TCPDUMP=0
  1508.     else:
  1509.         TCPDUMP=1
  1510.         
  1511.     
  1512.  
  1513. try:
  1514.     from Crypto.Cipher import ARC4
  1515. except ImportError:
  1516.     log_loading.info("Can't find Crypto python lib. Won't be able to decrypt WEP")
  1517.  
  1518.  
  1519. # Workarround bug 643005 : https://sourceforge.net/tracker/?func=detail&atid=105470&aid=643005&group_id=5470
  1520. try:
  1521.     socket.inet_aton("255.255.255.255")
  1522. except socket.error:
  1523.     def inet_aton(x):
  1524.         if x == "255.255.255.255":
  1525.             return "\xff"*4
  1526.         else:
  1527.             return socket.inet_aton(x)
  1528. else:
  1529.     inet_aton = socket.inet_aton
  1530.  
  1531. inet_ntoa = socket.inet_ntoa
  1532. try:
  1533.     inet_ntop = socket.inet_ntop
  1534.     inet_nton = socket.inet_pton
  1535. except AttributeError:
  1536.     log_loading.info("inet_ntop/pton functions not found. Python IPv6 support not present")
  1537.  
  1538.  
  1539. if SOLARIS:
  1540.     # GRE is missing on Solaris
  1541.     socket.IPPROTO_GRE = 47
  1542.  
  1543.  
  1544.  
  1545. ############
  1546. ## Consts ##
  1547. ############
  1548.  
  1549. ETHER_ANY = "\x00"*6
  1550. ETHER_BROADCAST = "\xff"*6
  1551.  
  1552. ETH_P_ALL = 3
  1553. ETH_P_IP = 0x800
  1554. ETH_P_ARP = 0x806
  1555.  
  1556. # From net/if_arp.h
  1557. ARPHDR_ETHER = 1
  1558. ARPHDR_METRICOM = 23
  1559. ARPHDR_PPP = 512
  1560. ARPHDR_LOOPBACK = 772
  1561.  
  1562. # From bits/ioctls.h
  1563. SIOCGIFHWADDR  = 0x8927          # Get hardware address    
  1564. SIOCGIFADDR    = 0x8915          # get PA address          
  1565. SIOCGIFNETMASK = 0x891b          # get network PA mask     
  1566. SIOCGIFNAME    = 0x8910          # get iface name          
  1567. SIOCSIFLINK    = 0x8911          # set iface channel       
  1568. SIOCGIFCONF    = 0x8912          # get iface list          
  1569. SIOCGIFFLAGS   = 0x8913          # get flags               
  1570. SIOCSIFFLAGS   = 0x8914          # set flags               
  1571. SIOCGIFINDEX   = 0x8933          # name -> if_index mapping
  1572. SIOCGIFCOUNT   = 0x8938          # get number of devices
  1573.  
  1574.  
  1575. # From if.h
  1576. IFF_UP = 0x1               # Interface is up.
  1577. IFF_BROADCAST = 0x2        # Broadcast address valid.
  1578. IFF_DEBUG = 0x4            # Turn on debugging.
  1579. IFF_LOOPBACK = 0x8         # Is a loopback net.
  1580. IFF_POINTOPOINT = 0x10     # Interface is point-to-point link.
  1581. IFF_NOTRAILERS = 0x20      # Avoid use of trailers.
  1582. IFF_RUNNING = 0x40         # Resources allocated.
  1583. IFF_NOARP = 0x80           # No address resolution protocol.
  1584. IFF_PROMISC = 0x100        # Receive all packets.
  1585.  
  1586.  
  1587.  
  1588. # From netpacket/packet.h
  1589. PACKET_ADD_MEMBERSHIP  = 1
  1590. PACKET_DROP_MEMBERSHIP = 2
  1591. PACKET_RECV_OUTPUT     = 3
  1592. PACKET_RX_RING         = 5
  1593. PACKET_STATISTICS      = 6
  1594. PACKET_MR_MULTICAST    = 0
  1595. PACKET_MR_PROMISC      = 1
  1596. PACKET_MR_ALLMULTI     = 2
  1597.  
  1598.  
  1599. # From bits/socket.h
  1600. SOL_PACKET = 263
  1601. # From asm/socket.h
  1602. SO_ATTACH_FILTER = 26
  1603. SOL_SOCKET = 1
  1604.  
  1605. # From net/route.h
  1606. RTF_UP = 0x0001  # Route usable
  1607.  
  1608. # From BSD net/bpf.h
  1609. #BIOCIMMEDIATE=0x80044270
  1610. BIOCIMMEDIATE=-2147204496
  1611.  
  1612. MTU = 1600
  1613.  
  1614.  
  1615. # file parsing to get some values :
  1616. spaces = re.compile("[ \t]+|\n")
  1617.  
  1618. IP_PROTOS={}
  1619. try:
  1620.     f=open("/etc/protocols")
  1621.     for l in f:
  1622.         try:
  1623.             if l[0] in ["#","\n"]:
  1624.                 continue
  1625.             lt = tuple(re.split(spaces, l))
  1626.             if len(lt) < 3:
  1627.                 continue
  1628.             IP_PROTOS.update({lt[2]:int(lt[1])})
  1629.         except:
  1630.             log_loading.info("Couldn't parse one line from protocols file (" + l + ")")
  1631.     f.close()
  1632. except IOError:
  1633.     log_loading.info("Can't open /etc/protocols file")
  1634.  
  1635. ETHER_TYPES={}
  1636. try:
  1637.     f=open("/etc/ethertypes")
  1638.     for l in f:
  1639.         try:
  1640.             if l[0] in ["#","\n"]:
  1641.                 continue
  1642.             lt = tuple(re.split(spaces, l))
  1643.             if len(lt) < 2:
  1644.                 continue
  1645.             ETHER_TYPES.update({lt[0]:int(lt[1], 16)})
  1646.         except:
  1647.             log_loading.info("Couldn't parse one line from ethertypes file (" + l + ")")
  1648.     f.close()
  1649. except IOError,msg:
  1650.     log_loading.info("Can't open /etc/ethertypes file")
  1651.  
  1652. TCP_SERVICES={}
  1653. UDP_SERVICES={}
  1654. try:
  1655.     f=open("/etc/services")
  1656.     for l in f:
  1657.         try:
  1658.             if l[0] in ["#","\n"]:
  1659.                 continue
  1660.             lt = tuple(re.split(spaces, l))
  1661.             if len(lt) < 2:
  1662.                 continue
  1663.             if lt[1].endswith("/tcp"):
  1664.                 TCP_SERVICES.update({lt[0]:int(lt[1].split('/')[0])})
  1665.             elif lt[1].endswith("/udp"):
  1666.                 UDP_SERVICES.update({lt[0]:int(lt[1].split('/')[0])})
  1667.         except:
  1668.             log_loading.warning("Couldn't parse one line from /etc/services file (" + l + ")")
  1669.     f.close()
  1670. except IOError:
  1671.     log_loading.info("Can't open /etc/services file")
  1672.  
  1673.  
  1674.  
  1675. ###########
  1676. ## Tools ##
  1677. ###########
  1678.  
  1679. def sane(x):
  1680.     r=""
  1681.     for i in x:
  1682.         j = ord(i)
  1683.         if (j < 32) or (j >= 127):
  1684.             r=r+conf.color_theme.not_printable(".")
  1685.         else:
  1686.             r=r+i
  1687.     return r
  1688.  
  1689. def hexdump(x):
  1690.     x=str(x)
  1691.     l = len(x)
  1692.     i = 0
  1693.     while i < l:
  1694.         print "%04x  " % i,
  1695.         for j in range(16):
  1696.             if i+j < l:
  1697.                 print "%02X" % ord(x[i+j]),
  1698.             else:
  1699.                 print "  ",
  1700.             if j%16 == 7:
  1701.                 print "",
  1702.         print " ",
  1703.         print sane(x[i:i+16])
  1704.         i += 16
  1705.  
  1706. def linehexdump(x, onlyasc=0):
  1707.     x = str(x)
  1708.     l = len(x)
  1709.     if not onlyasc:
  1710.         for i in range(l):
  1711.             print "%02X" % ord(x[i]),
  1712.         print "",
  1713.     print sane(x)
  1714.  
  1715. if BIG_ENDIAN:
  1716.     CRCPOLY=0x04c11db7L
  1717. else:
  1718.     CRCPOLY=0xedb88320L
  1719.  
  1720. def crc32(crc, x):
  1721.     for c in x:
  1722.         crc ^= ord(c)
  1723.         for i in range(8):
  1724.             if crc & 1:
  1725.                 y = CRCPOLY
  1726.             else:
  1727.                 y = 0
  1728.             crc >>= 1
  1729.             crc  ^= y
  1730.     return crc
  1731.  
  1732.  
  1733. def checksum(pkt):
  1734.     pkt=str(pkt)
  1735.     s=0
  1736.     if len(pkt) % 2 == 1:
  1737.         pkt += "\0"
  1738.     for i in range(len(pkt)/2):
  1739.         s = s +  (struct.unpack("!H",pkt[2*i:2*i+2])[0])
  1740.     s = (s >> 16) + (s & 0xffff)
  1741.     s += s >> 16
  1742.     return  ~s & 0xffff
  1743.  
  1744. def warning(x):
  1745.     log_runtime.warning(x)
  1746.  
  1747. def mac2str(mac):
  1748.     return "".join(map(lambda x: chr(int(x,16)), mac.split(":")))
  1749.  
  1750. def str2mac(s):
  1751.     return ("%02x:"*6)[:-1] % tuple(map(ord, s)) 
  1752.  
  1753. def strxor(x,y):
  1754.     return "".join(map(lambda x,y:chr(ord(x)^ord(y)),x,y))
  1755.  
  1756. def atol(x):
  1757.     try:
  1758.         ip = inet_aton(x)
  1759.     except socket.error:
  1760.         ip = inet_aton(socket.gethostbyname(x))
  1761.     return struct.unpack("I", ip)[0]
  1762. def ltoa(x):
  1763.     return inet_ntoa(struct.pack("I", x))
  1764.  
  1765. def itom(x):
  1766.     return socket.ntohl((0xffffffff00000000L>>x)&0xffffffffL)&0xffffffffL
  1767.  
  1768. def do_graph(graph,prog=None,type="svg",target=None):
  1769.     """do_graph(graph, prog=conf.prog.dot, type="svg",target="| conf.prog.display"):
  1770.     graph: GraphViz graph description
  1771.     type: output type (svg, ps, gif, jpg, etc.), passed to dot's "-T" option
  1772.     target: filename or redirect. Defaults pipe to Imagemagick's display program
  1773.     prog: which graphviz program to use"""
  1774.     if prog is None:
  1775.         prog = conf.prog.dot
  1776.     if target is None:
  1777.         target = "| %s" % conf.prog.display
  1778.     w,r = os.popen2("%s -T %s %s" % (prog,type,target))
  1779.     w.write(graph)
  1780.     w.close()
  1781.  
  1782. _TEX_TR = {
  1783.     "{":"{\\tt\\char123}",
  1784.     "}":"{\\tt\\char125}",
  1785.     "\\":"{\\tt\\char92}",
  1786.     "^":"\\^{}",
  1787.     "$":"\\$",
  1788.     "#":"\\#",
  1789.     "~":"\\~",
  1790.     "_":"\\_",
  1791.     "&":"\\&",
  1792.     "%":"\\%",
  1793.     "|":"{\\tt\\char124}",
  1794.     "~":"{\\tt\\char126}",
  1795.     "<":"{\\tt\\char60}",
  1796.     ">":"{\\tt\\char62}",
  1797.     }
  1798.     
  1799. def tex_escape(x):
  1800.     s = ""
  1801.     for c in x:
  1802.         s += _TEX_TR.get(c,c)
  1803.     return s
  1804.  
  1805. def colgen(*lstcol,**kargs):
  1806.     """Returns a generator that mixes provided quantities forever
  1807.     trans: a function to convert the three arguments into a color. lambda x,y,z:(x,y,z) by default"""
  1808.     if len(lstcol) < 2:
  1809.         lstcol *= 2
  1810.     trans = kargs.get("trans", lambda x,y,z: (x,y,z))
  1811.     while 1:
  1812.         for i in range(len(lstcol)):
  1813.             for j in range(len(lstcol)):
  1814.                 for k in range(len(lstcol)):
  1815.                     if i != j or j != k or k != i:
  1816.                         yield trans(lstcol[(i+j)%len(lstcol)],lstcol[(j+k)%len(lstcol)],lstcol[(k+i)%len(lstcol)])
  1817.  
  1818.  
  1819.  
  1820. ##############################
  1821. ## Session saving/restoring ##
  1822. ##############################
  1823.  
  1824.  
  1825. def save_session(fname, session=None, pickleProto=-1):
  1826.     if session is None:
  1827.         session = scapy_session
  1828.  
  1829.     to_be_saved = session.copy()
  1830.         
  1831.     if to_be_saved.has_key("__builtins__"):
  1832.         del(to_be_saved["__builtins__"])
  1833.  
  1834.     for k in to_be_saved.keys():
  1835.         if type(to_be_saved[k]) in [types.TypeType, types.ClassType, types.ModuleType]:
  1836.              log_interactive.error("[%s] (%s) can't be saved." % (k, type(to_be_saved[k])))
  1837.              del(to_be_saved[k])
  1838.  
  1839.     try:
  1840.         os.rename(fname, fname+".bak")
  1841.     except OSError:
  1842.         pass
  1843.     f=gzip.open(fname,"w")
  1844.     cPickle.dump(to_be_saved, f, pickleProto)
  1845.     f.close()
  1846.         
  1847.         
  1848.     
  1849.  
  1850. def load_session(fname):
  1851.     try:
  1852.         s = cPickle.load(gzip.open(fname))
  1853.     except IOError:
  1854.         s = cPickle.load(open(fname))
  1855.     scapy_session.clear()
  1856.     scapy_session.update(s)
  1857.  
  1858. def update_session(fname):
  1859.     try:
  1860.         s = cPickle.load(gzip.open(fname))
  1861.     except IOError:
  1862.         s = cPickle.load(open(fname))
  1863.     scapy_session.update(s)
  1864.  
  1865. def export_object(obj):
  1866.     print base64.encodestring(gzip.zlib.compress(cPickle.dumps(obj,2),9))
  1867.  
  1868. def import_object(obj=None):
  1869.     if obj is None:
  1870.         obj = sys.stdin.read()
  1871.     return cPickle.loads(gzip.zlib.decompress(base64.decodestring(obj.strip())))
  1872. def save_object(fname, obj):
  1873.     cPickle.dump(obj,gzip.open(fname,"w"))
  1874.  
  1875. def load_object(fname):
  1876.     return cPickle.load(gzip.open(fname))
  1877.  
  1878.  
  1879. #################
  1880. ## Debug class ##
  1881. #################
  1882.  
  1883. class debug:
  1884.     recv=[]
  1885.     sent=[]
  1886.     match=[]
  1887.  
  1888.  
  1889. ####################
  1890. ## IP Tools class ##
  1891. ####################
  1892.  
  1893. class IPTools:
  1894.     """Add more powers to a class that have a "src" attribute."""
  1895.     def whois(self):
  1896.         os.system("whois %s" % self.src)
  1897.     def ottl(self):
  1898.     t = [32,64,128,255]+[self.ttl]
  1899.     t.sort()
  1900.     return t[t.index(self.ttl)+1]
  1901.     def hops(self):
  1902.         return self.ottl()-self.ttl-1 
  1903.  
  1904.  
  1905. ##############################
  1906. ## Routing/Interfaces stuff ##
  1907. ##############################
  1908.  
  1909. class Route:
  1910.     def __init__(self):
  1911.         self.resync()
  1912.         self.s=socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
  1913.  
  1914.     def resync(self):
  1915.         self.routes = read_routes()
  1916.  
  1917.     def __repr__(self):
  1918.         rt = "Network         Netmask         Gateway         Iface           Output IP\n"
  1919.         for net,msk,gw,iface,addr in self.routes:
  1920.             rt += "%-15s %-15s %-15s %-15s %-15s\n" % (ltoa(net),
  1921.                                               ltoa(msk),
  1922.                                               gw,
  1923.                                               iface,
  1924.                                               addr)
  1925.         return rt
  1926.  
  1927.     def make_route(self, host=None, net=None, gw=None, dev=None):
  1928.         if host is not None:
  1929.             thenet,msk = host,32
  1930.         elif net is not None:
  1931.             thenet,msk = net.split("/")
  1932.             msk = int(msk)
  1933.         else:
  1934.             raise Exception("make_route: Incorrect parameters. You should specify a host or a net")
  1935.         if gw is None:
  1936.             gw="0.0.0.0"
  1937.         if dev is None:
  1938.             if gw:
  1939.                 nhop = gw
  1940.             else:
  1941.                 nhop = thenet
  1942.             dev,ifaddr,x = self.route(nhop)
  1943.         else:
  1944.             ifaddr = get_if_addr(dev)
  1945.         return (atol(thenet), itom(msk), gw, dev, ifaddr)
  1946.  
  1947.     def add(self, *args, **kargs):
  1948.         """Ex:
  1949.         add(net="192.168.1.0/24",gw="1.2.3.4")
  1950.         """
  1951.         self.routes.append(self.make_route(*args,**kargs))
  1952.  
  1953.         
  1954.     def delt(self,  *args, **kargs):
  1955.         route = self.make_route(*args,**kargs)
  1956.         try:
  1957.             i=self.routes.index(route)
  1958.             del(self.routes[i])
  1959.         except ValueError:
  1960.             warning("no matching route found")
  1961.              
  1962.     def ifchange(self, iff, addr):
  1963.         the_addr,the_msk = (addr.split("/")+["32"])[:2]
  1964.         the_msk = itom(int(the_msk))
  1965.         the_rawaddr, = struct.unpack("I",inet_aton(the_addr))
  1966.         the_net = the_rawaddr & the_msk
  1967.         
  1968.         
  1969.         for i in range(len(self.routes)):
  1970.             net,msk,gw,iface,addr = self.routes[i]
  1971.             if iface != iff:
  1972.                 continue
  1973.             if gw == '0.0.0.0':
  1974.                 self.routes[i] = (the_net,the_msk,gw,iface,the_addr)
  1975.             else:
  1976.                 self.routes[i] = (net,msk,gw,iface,the_addr)
  1977.         for i in arp_cache.keys():
  1978.             del(arp_cache[i])
  1979.         
  1980.                 
  1981.  
  1982.     def ifdel(self, iff):
  1983.         new_routes=[]
  1984.         for rt in self.routes:
  1985.             if rt[3] != iff:
  1986.                 new_routes.append(rt)
  1987.         self.routes=new_routes
  1988.         
  1989.     def ifadd(self, iff, addr):
  1990.         the_addr,the_msk = (addr.split("/")+["32"])[:2]
  1991.         the_msk = itom(int(the_msk))
  1992.         the_rawaddr, = struct.unpack("I",inet_aton(the_addr))
  1993.         the_net = the_rawaddr & the_msk
  1994.         self.routes.append((the_net,the_msk,'0.0.0.0',iff,the_addr))
  1995.  
  1996.  
  1997.     def route(self,dst):
  1998.         # Transform "192.168.*.1-5" to one IP of the set
  1999.         dst = dst.split("/")[0]
  2000.         dst = dst.replace("*","0") 
  2001.         while 1:
  2002.             l = dst.find("-")
  2003.             if l < 0:
  2004.                 break
  2005.             m = (dst[l:]+".").find(".")
  2006.             dst = dst[:l]+dst[l+m:]
  2007.  
  2008.             
  2009.         try:
  2010.             dst=inet_aton(dst)
  2011.         except socket.error:
  2012.             dst=inet_aton(socket.gethostbyname(dst))
  2013.         dst,=struct.unpack("I",dst)
  2014.         pathes=[]
  2015.         for d,m,gw,i,a in self.routes:
  2016.             aa, = struct.unpack("I",inet_aton(a))
  2017.             if aa == dst:
  2018.                 pathes.append((0xffffffffL,("lo",a,"0.0.0.0")))
  2019.             if (dst & m) == (d & m):
  2020.                 pathes.append((m,(i,a,gw)))
  2021.         if not pathes:
  2022.             warning("No route found (no default route?)")
  2023.             return "lo","0.0.0.0","0.0.0.0" #XXX linux specific!
  2024.         # Choose the more specific route (greatest netmask).
  2025.         # XXX: we don't care about metrics
  2026.         pathes.sort()
  2027.         return pathes[-1][1] 
  2028.             
  2029.     def get_if_bcast(self, iff):
  2030.         for net, msk, gw, iface, addr in self.routes:
  2031.             if (iff == iface and net != 0L):
  2032.                 bcast = atol(addr)|(~msk&0xffffffffL); # FIXME: check error in atol()
  2033.                 return ltoa(bcast);
  2034.         warning("No broadcast address found for iface %s\n" % iff);
  2035.  
  2036. if DNET:
  2037.     def get_if_raw_hwaddr(iff):
  2038.         if iff[:2] == "lo":
  2039.             return (772, '\x00'*6)
  2040.         try:
  2041.             l = dnet.intf().get(iff)
  2042.             l = l["link_addr"]
  2043.         except:
  2044.             raise Exception("Error in attempting to get hw address for interface [%s]" % iff)
  2045.         return l.type,l.data
  2046.     def get_if_raw_addr(ifname):
  2047.         i = dnet.intf()
  2048.         return i.get(ifname)["addr"].data
  2049. else:
  2050.     def get_if_raw_hwaddr(iff):
  2051.         return struct.unpack("16xh6s8x",get_if(iff,SIOCGIFHWADDR))
  2052.  
  2053.     def get_if_raw_addr(iff):
  2054.         s=socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
  2055.         ifreq = ioctl(s, SIOCGIFADDR, struct.pack("16s16x",iff))
  2056.         return ifreq[20:24]
  2057.  
  2058.  
  2059.  
  2060. if PCAP:
  2061.     def get_if_list():
  2062.         # remove 'any' interface
  2063.         return map(lambda x:x[0],filter(lambda x:x[1] is None,pcap.findalldevs()))
  2064.     def get_working_if():
  2065.         try:
  2066.             return pcap.lookupdev()
  2067.         except pcap.pcapc.EXCEPTION:
  2068.             return 'lo'
  2069.  
  2070.     def attach_filter(s, filter):
  2071.         warning("attach_filter() should not be called in PCAP mode")
  2072.     def set_promisc(s,iff,val=1):
  2073.         warning("set_promisc() should not be called in DNET/PCAP mode")
  2074.     
  2075. else:
  2076.     def get_if_list():
  2077.         f=open("/proc/net/dev","r")
  2078.         lst = []
  2079.         f.readline()
  2080.         f.readline()
  2081.         for l in f:
  2082.             lst.append(l.split(":")[0].strip())
  2083.         return lst
  2084.     def get_working_if():
  2085.         for i in get_if_list():
  2086.             if i == 'lo':                
  2087.                 continue
  2088.             ifflags = struct.unpack("16xH14x",get_if(i,SIOCGIFFLAGS))[0]
  2089.             if ifflags & IFF_UP:
  2090.                 return i
  2091.         return "lo"
  2092.     def attach_filter(s, filter):
  2093.         # XXX We generate the filter on the interface conf.iface 
  2094.         # because tcpdump open the "any" interface and ppp interfaces
  2095.         # in cooked mode. As we use them in raw mode, the filter will not
  2096.         # work... one solution could be to use "any" interface and translate
  2097.         # the filter from cooked mode to raw mode
  2098.         # mode
  2099.         if not TCPDUMP:
  2100.             return
  2101.         try:
  2102.             f = os.popen("%s -i %s -ddd -s 1600 '%s'" % (conf.prog.tcpdump,conf.iface,filter))
  2103.         except OSError,msg:
  2104.             log_interactive.warning("Failed to execute tcpdump: (%s)")
  2105.             return
  2106.         lines = f.readlines()
  2107.         if f.close():
  2108.             raise Exception("Filter parse error")
  2109.         nb = int(lines[0])
  2110.         bpf = ""
  2111.         for l in lines[1:]:
  2112.             bpf += struct.pack("HBBI",*map(long,l.split()))
  2113.     
  2114.         # XXX. Argl! We need to give the kernel a pointer on the BPF,
  2115.         # python object header seems to be 20 bytes. 36 bytes for x86 64bits arch.
  2116.         if X86_64:
  2117.             bpfh = struct.pack("HI", nb, id(bpf)+36)
  2118.         else:
  2119.             bpfh = struct.pack("HI", nb, id(bpf)+20)  
  2120.         s.setsockopt(SOL_SOCKET, SO_ATTACH_FILTER, bpfh)
  2121.  
  2122.     def set_promisc(s,iff,val=1):
  2123.         mreq = struct.pack("IHH8s", get_if_index(iff), PACKET_MR_PROMISC, 0, "")
  2124.         if val:
  2125.             cmd = PACKET_ADD_MEMBERSHIP
  2126.         else:
  2127.             cmd = PACKET_DROP_MEMBERSHIP
  2128.         s.setsockopt(SOL_PACKET, cmd, mreq)
  2129.  
  2130.  
  2131. if not LINUX:
  2132.  
  2133.     def new_read_routes():
  2134.  
  2135.         rtlst = []
  2136.         def addrt(rt,lst):
  2137.             dst,gw = rt
  2138.             lst.append(rt)
  2139.  
  2140.         r = dnet.route()
  2141.         print r.loop(addrt, rtlst)
  2142.         return rtlst
  2143.  
  2144.     def read_routes():
  2145.         if SOLARIS:
  2146.             f=os.popen("netstat -rvn") # -f inet
  2147.         else:
  2148.             f=os.popen("netstat -rn") # -f inet
  2149.         ok = 0
  2150.         mtu_present = False
  2151.         routes = []
  2152.         for l in f.readlines():
  2153.             if not l:
  2154.                 break
  2155.             l = l.strip()
  2156.             if l.find("----") >= 0: # a separation line
  2157.                 continue
  2158.             if l.find("Destination") >= 0:
  2159.                 ok = 1
  2160.                 if l.find("Mtu") >= 0:
  2161.                     mtu_present = True
  2162.                 continue
  2163.             if ok == 0:
  2164.                 continue
  2165.             if not l:
  2166.                 break
  2167.             if SOLARIS:
  2168.                 dest,mask,gw,netif,mxfrg,rtt,ref,flg = l.split()[:8]
  2169.             else:
  2170.                 if mtu_present:
  2171.                     dest,gw,flg,ref,use,mtu,netif = l.split()[:7]
  2172.                 else:
  2173.                     dest,gw,flg,ref,use,netif = l.split()[:6]
  2174.             if flg.find("Lc") >= 0:
  2175.                 continue                
  2176.             if dest == "default":
  2177.                 dest = 0L
  2178.                 netmask = 0L
  2179.             else:
  2180.                 if SOLARIS:
  2181.                     netmask, = struct.unpack("I",inet_aton(mask))
  2182.                 elif "/" in dest:
  2183.                     dest,netmask = dest.split("/")
  2184.                     netmask = itom(int(netmask))
  2185.                 else:
  2186.                     netmask = itom((dest.count(".") + 1) * 8)
  2187.                 dest += ".0"*(3-dest.count("."))
  2188.                 dest, = struct.unpack("I",inet_aton(dest))
  2189.             if not "G" in flg:
  2190.                 gw = '0.0.0.0'
  2191.             ifaddr = get_if_addr(netif)
  2192.             routes.append((dest,netmask,gw,netif,ifaddr))
  2193.         f.close()
  2194.         return routes
  2195.  
  2196.     def read_interfaces():
  2197.         i = dnet.intf()
  2198.         ifflist = {}
  2199.         def addif(iff,lst):
  2200.             if not iff.has_key("addr"):
  2201.                 return
  2202.             if not iff.has_key("link_addr"):
  2203.                 return
  2204.             rawip = iff["addr"].data
  2205.             ip = inet_ntoa(rawip)
  2206.             rawll = iff["link_addr"].data
  2207.             ll = str2mac(rawll)
  2208.             lst[iff["name"]] = (rawll,ll,rawip,ip)
  2209.         i.loop(addif, ifflist)
  2210.         return ifflist
  2211.  
  2212.             
  2213. else:
  2214.  
  2215.     def read_routes():
  2216.         f=open("/proc/net/route","r")
  2217.         routes = []
  2218.         s=socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
  2219.         ifreq = ioctl(s, SIOCGIFADDR,struct.pack("16s16x","lo"))
  2220.         addrfamily = struct.unpack("h",ifreq[16:18])[0]
  2221.         if addrfamily == socket.AF_INET:
  2222.             ifreq2 = ioctl(s, SIOCGIFNETMASK,struct.pack("16s16x","lo"))
  2223.             msk = struct.unpack("I",ifreq2[20:24])[0]
  2224.             dst = struct.unpack("I",ifreq[20:24])[0] & msk
  2225.             ifaddr = inet_ntoa(ifreq[20:24])
  2226.             routes.append((dst, msk, "0.0.0.0", "lo", ifaddr))
  2227.         else:
  2228.             warning("Interface lo: unkownn address family (%i)"% addrfamily)
  2229.     
  2230.         for l in f.readlines()[1:]:
  2231.             iff,dst,gw,flags,x,x,x,msk,x,x,x = l.split()
  2232.             if int(flags,16) & RTF_UP == 0:
  2233.                 continue
  2234.             ifreq = ioctl(s, SIOCGIFADDR,struct.pack("16s16x",iff))
  2235.             addrfamily = struct.unpack("h",ifreq[16:18])[0]
  2236.             if addrfamily == socket.AF_INET:
  2237.                 ifaddr = inet_ntoa(ifreq[20:24])
  2238.             else:
  2239.                 warning("Interface %s: unkownn address family (%i)"%(iff, addrfamily))
  2240.                 continue
  2241.             routes.append((long(dst,16),
  2242.                           long(msk,16),
  2243.                           inet_ntoa(struct.pack("I",long(gw,16))),
  2244.                           iff, ifaddr))
  2245.         
  2246.         f.close()
  2247.         return routes
  2248.  
  2249.     def get_if(iff,cmd):
  2250.         s=socket.socket()
  2251.         ifreq = ioctl(s, cmd, struct.pack("16s16x",iff))
  2252.         s.close()
  2253.         return ifreq
  2254.  
  2255.  
  2256.     def get_if_index(iff):
  2257.         return int(struct.unpack("I",get_if(iff, SIOCGIFINDEX)[16:20])[0])
  2258.  
  2259.  
  2260.     
  2261. def get_if_addr(iff):
  2262.     return inet_ntoa(get_if_raw_addr(iff))
  2263.     
  2264. def get_if_hwaddr(iff):
  2265.     addrfamily, mac = get_if_raw_hwaddr(iff)
  2266.     if addrfamily in [ARPHDR_ETHER,ARPHDR_LOOPBACK]:
  2267.         return str2mac(mac)
  2268.     else:
  2269.         raise Exception("Unsupported address family (%i)"%addrfamily)
  2270.  
  2271.  
  2272.  
  2273. #####################
  2274. ## ARP cache stuff ##
  2275. #####################
  2276.  
  2277. ARPTIMEOUT=120
  2278.  
  2279. # XXX Fill arp_cache with /etc/ether and arp cache
  2280. arp_cache={}
  2281.  
  2282. if 0 and DNET: ## XXX Can't use this because it does not resolve IPs not in cache
  2283.     dnet_arp_object = dnet.arp()
  2284.     def getmacbyip(ip):
  2285.         iff,a,gw = conf.route.route(ip)
  2286.         if iff == "lo":
  2287.             return "ff:ff:ff:ff:ff:ff"
  2288.         if gw != "0.0.0.0":
  2289.             ip = gw
  2290.         res = dnet_arp_object.get(dnet.addr(ip))
  2291.         if res is None:
  2292.             return None
  2293.         else:
  2294.             return res.ntoa()
  2295. else:
  2296.     def getmacbyip(ip):
  2297.         iff,a,gw = conf.route.route(ip)
  2298.         if ( (iff == "lo") or (ip == conf.route.get_if_bcast(iff)) ):
  2299.             return "ff:ff:ff:ff:ff:ff"
  2300.         if gw != "0.0.0.0":
  2301.             ip = gw
  2302.     
  2303.         if arp_cache.has_key(ip):
  2304.             mac, timeout = arp_cache[ip]
  2305.             if timeout and (time.time()-timeout < ARPTIMEOUT):
  2306.                 return mac
  2307.         
  2308.         res = srp1(Ether(dst=ETHER_BROADCAST)/ARP(op="who-has", pdst=ip),
  2309.                   type=ETH_P_ARP,
  2310.                   iface = iff,
  2311.                   timeout=2,
  2312.                   verbose=0,
  2313.                   nofilter=1)
  2314.         if res is not None:
  2315.             mac = res.payload.hwsrc
  2316.             arp_cache[ip] = (mac,time.time())
  2317.             return mac
  2318.         return None
  2319.     
  2320.  
  2321. ####################
  2322. ## Random numbers ##
  2323. ####################
  2324.  
  2325. class VolatileValue:
  2326.     def __repr__(self):
  2327.         return "<%s>" % self.__class__.__name__
  2328.     def __getattr__(self, attr):
  2329.         return getattr(self._fix(),attr)
  2330.     def _fix(self):
  2331.         return None
  2332.  
  2333.  
  2334. class RandField(VolatileValue):
  2335.     pass
  2336.  
  2337.  
  2338. class RandNum(RandField):
  2339.     min = 0
  2340.     max = 0
  2341.     def __init__(self, min, max):
  2342.         self.min = min
  2343.         self.max = max
  2344.     def _fix(self):
  2345.         # XXX: replace with sth that guarantee unicity
  2346.         return random.randint(self.min, self.max)
  2347.  
  2348. class RandByte(RandNum):
  2349.     def __init__(self):
  2350.         RandNum.__init__(self, 0, 255)
  2351.  
  2352. class RandShort(RandNum):
  2353.     def __init__(self):
  2354.         RandNum.__init__(self, 0, 65535)
  2355.  
  2356. class RandInt(RandNum):
  2357.     def __init__(self):
  2358.         # Well, 2147483647 won't be reached because max+1 must be int
  2359.         # and 2147483647+1 is longint. (random module limitation)
  2360.         RandNum.__init__(self, 0, 2147483646)
  2361.  
  2362. class RandLong(RandNum):
  2363.     def __init__(self):
  2364.         RandNum.__init__(self, 0, 2L**64-1)
  2365.  
  2366.  
  2367. class RandString(RandField):
  2368.     def __init__(self, size, chars="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"):
  2369.         self.chars = chars
  2370.         self.size = size
  2371.     def _fix(self):
  2372.         s = ""
  2373.         for i in range(self.size):
  2374.             s += random.choice(self.chars)
  2375.         return s
  2376.  
  2377. class RandBin(RandString):
  2378.     def __init__(self, size):
  2379.         RandString.__init__(self, size, "".join(map(chr,range(256))))
  2380.  
  2381.  
  2382. class RandTermString(RandString):
  2383.     def __init__(self, size, term):
  2384.         RandString.__init__(self, size, "".join(map(chr,range(1,256))))
  2385.         self.term = term
  2386.     def _fix(self):
  2387.         return RandString._fix(self)+self.term
  2388.     
  2389.     
  2390.  
  2391. class RandIP(RandString):
  2392.     def __init__(self, iptemplate="0.0.0.0/0"):
  2393.         self.ip = Net(iptemplate)
  2394.     def _fix(self):
  2395.         return self.ip.choice()
  2396.  
  2397. class RandMAC(RandString):
  2398.     def __init__(self, template="*"):
  2399.         template += ":*:*:*:*:*"
  2400.         template = template.split(":")
  2401.         self.mac = ()
  2402.         for i in range(6):
  2403.             if template[i] == "*":
  2404.                 v = RandByte()
  2405.             elif "-" in template[i]:
  2406.                 x,y = template[i].split("-")
  2407.                 v = RandNum(int(x,16), int(y,16))
  2408.             else:
  2409.                 v = int(template[i],16)
  2410.             self.mac += (v,)
  2411.     def _fix(self):
  2412.         return "%02x:%02x:%02x:%02x:%02x:%02x" % self.mac
  2413.     
  2414.  
  2415. # Automatic timestamp
  2416.  
  2417. class AutoTime(VolatileValue):
  2418.     def __init__(self, base=None):
  2419.         if base == None:
  2420.             self.diff = 0
  2421.         else:
  2422.             self.diff = time.time()-base
  2423.     def _fix(self):
  2424.         return time.time()-self.diff
  2425.             
  2426. class IntAutoTime(AutoTime):
  2427.     def _fix(self):
  2428.         return int(AutoTime.current_val(self))
  2429.  
  2430.  
  2431.  
  2432. class DelayedEval(VolatileValue):
  2433.     """ Exemple of usage: DelayedEval("time.time()") """
  2434.     def __init__(self, expr):
  2435.         self.expr = expr
  2436.     def _fix(self):
  2437.         return eval(self.expr)
  2438.  
  2439.  
  2440.  
  2441.  
  2442. ################
  2443. ## Generators ##
  2444. ################
  2445.  
  2446. class Gen(object):
  2447.     def __iter__(self):
  2448.         return iter([])
  2449.     
  2450. class SetGen(Gen):
  2451.     def __init__(self, set):
  2452.         if type(set) is list:
  2453.             self.set = set
  2454.         elif isinstance(set, PacketList):
  2455.             self.set = list(set)
  2456.         else:
  2457.             self.set = [set]
  2458.     def transf(self, element):
  2459.         return element
  2460.     def __iter__(self):
  2461.         for i in self.set:
  2462.             if (type(i) is tuple) and (len(i) == 2):
  2463.                 if  (i[0] <= i[1]):
  2464.                     j=i[0]
  2465.                     while j <= i[1]:
  2466.                         yield j
  2467.                         j += 1
  2468.             elif isinstance(i, Gen):
  2469.                 for j in i:
  2470.                     yield j
  2471.             else:
  2472.                 yield i
  2473.     def __repr__(self):
  2474.         return "<SetGen %s>" % self.set.__repr__()
  2475.  
  2476. class Net(Gen):
  2477.     """Generate a list of IPs from a network address or a name"""
  2478.     name = "ip"
  2479.     ipaddress = re.compile(r"^(\*|[0-2]?[0-9]?[0-9](-[0-2]?[0-9]?[0-9])?)\.(\*|[0-2]?[0-9]?[0-9](-[0-2]?[0-9]?[0-9])?)\.(\*|[0-2]?[0-9]?[0-9](-[0-2]?[0-9]?[0-9])?)\.(\*|[0-2]?[0-9]?[0-9](-[0-2]?[0-9]?[0-9])?)(/[0-3]?[0-9])?$")
  2480.     def __init__(self, net):
  2481.         self.repr=net
  2482.  
  2483.         tmp=net.split('/')+["32"]
  2484.         if not self.ipaddress.match(net):
  2485.             tmp[0]=socket.gethostbyname(tmp[0])
  2486.         netmask = int(tmp[1])
  2487.  
  2488.         def parse_digit(a,netmask):
  2489.             netmask = min(8,max(netmask,0))
  2490.             if a == "*":
  2491.                 a = (0,256)
  2492.             elif a.find("-") >= 0:
  2493.                 x,y = map(int,a.split("-"))
  2494.                 if x > y:
  2495.                     y = x
  2496.                 a = (x &  (0xffL<<netmask) , max(y, (x | (0xffL>>(8-netmask))))+1)
  2497.             else:
  2498.                 a = (int(a) & (0xffL<<netmask),(int(a) | (0xffL>>(8-netmask)))+1)
  2499.             return a
  2500.  
  2501.         self.parsed = map(lambda x,y: parse_digit(x,y), tmp[0].split("."), map(lambda x,nm=netmask: x-nm, (8,16,24,32)))
  2502.                                                                                                
  2503.     def __iter__(self):
  2504.         for d in xrange(*self.parsed[3]):
  2505.             for c in xrange(*self.parsed[2]):
  2506.                 for b in xrange(*self.parsed[1]):
  2507.                     for a in xrange(*self.parsed[0]):
  2508.                         yield "%i.%i.%i.%i" % (a,b,c,d)
  2509.     def choice(self):
  2510.         ip = []
  2511.         for v in self.parsed:
  2512.             ip.append(str(random.randint(v[0],v[1]-1)))
  2513.         return ".".join(ip) 
  2514.                           
  2515.     def __repr__(self):
  2516.         return "<Net %s>" % self.repr
  2517.  
  2518.  
  2519. #############
  2520. ## Results ##
  2521. #############
  2522.  
  2523. class PacketList:
  2524.     res = []
  2525.     def __init__(self, res, name="PacketList", stats=None):
  2526.         """create a packet list from a list of packets
  2527.            res: the list of packets
  2528.            stats: a list of classes that will appear in the stats (defaults to [TCP,UDP,ICMP])"""
  2529.         if stats is None:
  2530.             stats = [ TCP,UDP,ICMP ]
  2531.         self.stats = stats
  2532.         self.res = res
  2533.         self.listname = name
  2534.     def _elt2pkt(self, elt):
  2535.         return elt
  2536.     def _elt2sum(self, elt):
  2537.         return elt.summary()
  2538.     def _elt2show(self, elt):
  2539.         return self._elt2sum(elt)
  2540.     def __repr__(self):
  2541. #        stats=dict.fromkeys(self.stats,0) ## needs python >= 2.3  :(
  2542.         stats = dict(map(lambda x: (x,0), self.stats))
  2543.         other = 0
  2544.         for r in self.res:
  2545.             f = 0
  2546.             for p in stats:
  2547.                 if self._elt2pkt(r).haslayer(p):
  2548.                     stats[p] += 1
  2549.                     f = 1
  2550.                     break
  2551.             if not f:
  2552.                 other += 1
  2553.         s = ""
  2554.         ct = conf.color_theme
  2555.         for p in stats:
  2556.             s += " %s%s%s" % (ct.packetlist_proto(p.name),
  2557.                               ct.punct(":"),
  2558.                               ct.packetlist_value(stats[p]))
  2559.         s += " %s%s%s" % (ct.packetlist_proto("Other"),
  2560.                           ct.punct(":"),
  2561.                           ct.packetlist_value(other))
  2562.         return "%s%s%s%s%s" % (ct.punct("<"),
  2563.                                ct.packetlist_name(self.listname),
  2564.                                ct.punct(":"),
  2565.                                s,
  2566.                                ct.punct(">"))
  2567.     def __getattr__(self, attr):
  2568.         return getattr(self.res, attr)
  2569.     def __getitem__(self, item):
  2570.         if type(item) is type and issubclass(item,Packet):
  2571.             return self.__class__(filter(lambda x: item in self._elt2pkt(x),self.res),
  2572.                                   name="%s from %s"%(item.__name__,self.listname))
  2573.         if type(item) is slice:
  2574.             return self.__class__(self.res.__getitem__(item),
  2575.                                   name = "mod %s" % self.listname)
  2576.         return self.res.__getitem__(item)
  2577.     def __getslice__(self, *args, **kargs):
  2578.         return self.__class__(self.res.__getslice__(*args, **kargs),
  2579.                               name="mod %s"%self.listname)
  2580.     def __add__(self, other):
  2581.         return self.__class__(self.res+other.res,
  2582.                               name="%s+%s"%(self.listname,other.listname))
  2583.     def summary(self, prn=None, lfilter=None):
  2584.         """prints a summary of each packet
  2585. prn:     function to apply to each packet instead of lambda x:x.summary()
  2586. lfilter: truth function to apply to each packet to decide whether it will be displayed"""
  2587.         for r in self.res:
  2588.             if lfilter is not None:
  2589.                 if not lfilter(r):
  2590.                     continue
  2591.             if prn is None:
  2592.                 print self._elt2sum(r)
  2593.             else:
  2594.                 print prn(r)
  2595.     def nsummary(self,prn=None, lfilter=None):
  2596.         """prints a summary of each packet with the packet's number
  2597. prn:     function to apply to each packet instead of lambda x:x.summary()
  2598. lfilter: truth function to apply to each packet to decide whether it will be displayed"""
  2599.         for i in range(len(self.res)):
  2600.             if lfilter is not None:
  2601.                 if not lfilter(self.res[i]):
  2602.                     continue
  2603.             print conf.color_theme.id(i,"%04i"),
  2604.             if prn is None:
  2605.                 print self._elt2sum(self.res[i])
  2606.             else:
  2607.                 print prn(self.res[i])
  2608.     def display(self): # Deprecated. Use show()
  2609.         """deprecated. is show()"""
  2610.         self.show()
  2611.     def show(self, *args, **kargs):
  2612.         """Best way to display the packet list. Defaults to nsummary() method"""
  2613.         return self.nsummary(*args, **kargs)
  2614.     
  2615.     def filter(self, func):
  2616.         """Returns a packet list filtered by a truth function"""
  2617.         return self.__class__(filter(func,self.res),
  2618.                               name="filtered %s"%self.listname)
  2619.     def make_table(self, *args, **kargs):
  2620.         """Prints a table using a function that returs for each packet its head column value, head row value and displayed value
  2621.         ex: p.make_table(lambda x:(x[IP].dst, x[TCP].dport, x[TCP].sprintf("%flags%")) """
  2622.         return make_table(self.res, *args, **kargs)
  2623.     def make_lined_table(self, *args, **kargs):
  2624.         """Same as make_table, but print a table with lines"""
  2625.         return make_lined_table(self.res, *args, **kargs)
  2626.     def make_tex_table(self, *args, **kargs):
  2627.         """Same as make_table, but print a table with LaTeX syntax"""
  2628.         return make_tex_table(self.res, *args, **kargs)
  2629.  
  2630.     def plot(self, f, lfilter=None,**kargs):
  2631.         """Applies a function to each packet to get a value that will be plotted with GnuPlot. A gnuplot object is returned
  2632.         lfilter: a truth function that decides whether a packet must be ploted"""
  2633.         g=Gnuplot.Gnuplot()
  2634.         l = map(f,self.res)
  2635.         if lfilter is not None:
  2636.             l = filter(lfilter, l)
  2637.         g.plot(Gnuplot.Data(l, **kargs))
  2638.         return g
  2639.  
  2640.     def hexdump(self):
  2641.         """Prints an hexadecimal dump of each packet in the list"""
  2642.         for p in self:
  2643.             hexdump(self._elt2pkt(p))
  2644.  
  2645.     def hexraw(self, lfilter=None):
  2646.         """Same as nsummary(), except that if a packet has a Raw layer, it will be hexdumped
  2647.         lfilter: a truth function that decides whether a packet must be displayed"""
  2648.         for i in range(len(self.res)):
  2649.             p = self._elt2pkt(self.res[i])
  2650.             if lfilter is not None and not lfilter(p):
  2651.                 continue
  2652.             print "%s %s %s" % (conf.color_theme.id(i,"%04i"),
  2653.                                 p.sprintf("%.time%"),
  2654.                                 self._elt2sum(self.res[i]))
  2655.             if p.haslayer(Raw):
  2656.                 hexdump(p.getlayer(Raw).load)
  2657.  
  2658.     def padding(self, lfilter=None):
  2659.         """Same as hexraw(), for Padding layer"""
  2660.         for i in range(len(self.res)):
  2661.             p = self._elt2pkt(self.res[i])
  2662.             if p.haslayer(Padding):
  2663.                 if lfilter is None or lfilter(p):
  2664.                     print "%s %s %s" % (conf.color_theme.id(i,"%04i"),
  2665.                                         p.sprintf("%.time%"),
  2666.                                         self._elt2sum(self.res[i]))
  2667.                     hexdump(p.getlayer(Padding).load)
  2668.  
  2669.     def nzpadding(self, lfilter=None):
  2670.         """Same as padding() but only non null padding"""
  2671.         for i in range(len(self.res)):
  2672.             p = self._elt2pkt(self.res[i])
  2673.             if p.haslayer(Padding):
  2674.                 pad = p.getlayer(Padding).load
  2675.                 if pad == pad[0]*len(pad):
  2676.                     continue
  2677.                 if lfilter is None or lfilter(p):
  2678.                     print "%s %s %s" % (conf.color_theme.id(i,"%04i"),
  2679.                                         p.sprintf("%.time%"),
  2680.                                         self._elt2sum(self.res[i]))
  2681.                     hexdump(p.getlayer(Padding).load)
  2682.         
  2683.  
  2684.     def conversations(self, getsrcdst=None,**kargs):
  2685.         """Graphes a conversations between sources and destinations and display it
  2686.         (using graphviz and imagemagick)
  2687.         getsrcdst: a function that takes an element of the list and return the source and dest
  2688.                    by defaults, return source and destination IP
  2689.         type: output type (svg, ps, gif, jpg, etc.), passed to dot's "-T" option
  2690.         target: filename or redirect. Defaults pipe to Imagemagick's display program
  2691.         prog: which graphviz program to use"""
  2692.         if getsrcdst is None:
  2693.             getsrcdst = lambda x:(x[IP].src, x[IP].dst)
  2694.         conv = {}
  2695.         for p in self.res:
  2696.             p = self._elt2pkt(p)
  2697.             try:
  2698.                 c = getsrcdst(p)
  2699.             except:
  2700.                 #XXX warning()
  2701.                 continue
  2702.             conv[c] = conv.get(c,0)+1
  2703.         gr = 'digraph "conv" {\n'
  2704.         for s,d in conv:
  2705.             gr += '\t "%s" -> "%s"\n' % (s,d)
  2706.         gr += "}\n"        
  2707.         do_graph(gr, **kargs)
  2708.  
  2709.     def afterglow(self, src=None, event=None, dst=None, **kargs):
  2710.         """Experimental clone attempt of http://sourceforge.net/projects/afterglow
  2711.         each datum is reduced as src -> event -> dst and the data are graphed.
  2712.         by default we have IP.src -> IP.dport -> IP.dst"""
  2713.         if src is None:
  2714.             src = lambda x: x[IP].src
  2715.         if event is None:
  2716.             event = lambda x: x[IP].dport
  2717.         if dst is None:
  2718.             dst = lambda x: x[IP].dst
  2719.         sl = {}
  2720.         el = {}
  2721.         dl = {}
  2722.         for i in self.res:
  2723.             try:
  2724.                 s,e,d = src(i),event(i),dst(i)
  2725.                 if s in sl:
  2726.                     n,l = sl[s]
  2727.                     n += 1
  2728.                     if e not in l:
  2729.                         l.append(e)
  2730.                     sl[s] = (n,l)
  2731.                 else:
  2732.                     sl[s] = (1,[e])
  2733.                 if e in el:
  2734.                     n,l = el[e]
  2735.                     n+=1
  2736.                     if d not in l:
  2737.                         l.append(d)
  2738.                     el[e] = (n,l)
  2739.                 else:
  2740.                     el[e] = (1,[d])
  2741.                 dl[d] = dl.get(d,0)+1
  2742.             except:
  2743.                 continue
  2744.  
  2745.         import math
  2746.         def normalize(n):
  2747.             return 2+math.log(n)/4.0
  2748.  
  2749.         def minmax(x):
  2750.             m,M = min(x),max(x)
  2751.             if m == M:
  2752.                 m = 0
  2753.             if M == 0:
  2754.                 M = 1
  2755.             return m,M
  2756.  
  2757.         mins,maxs = minmax(map(lambda (x,y): x, sl.values()))
  2758.         mine,maxe = minmax(map(lambda (x,y): x, el.values()))
  2759.         mind,maxd = minmax(dl.values())
  2760.     
  2761.         gr = 'digraph "afterglow" {\n\tedge [len=2.5];\n'
  2762.  
  2763.         gr += "# src nodes\n"
  2764.         for s in sl:
  2765.             n,l = sl[s]; n = 1+float(n-mins)/(maxs-mins)
  2766.             gr += '"src.%s" [label = "%s", shape=box, fillcolor="#FF0000", style=filled, fixedsize=1, height=%.2f,width=%.2f];\n' % (`s`,`s`,n,n)
  2767.         gr += "# event nodes\n"
  2768.         for e in el:
  2769.             n,l = el[e]; n = n = 1+float(n-mine)/(maxe-mine)
  2770.             gr += '"evt.%s" [label = "%s", shape=circle, fillcolor="#00FFFF", style=filled, fixedsize=1, height=%.2f, width=%.2f];\n' % (`e`,`e`,n,n)
  2771.         for d in dl:
  2772.             n = dl[d]; n = n = 1+float(n-mind)/(maxd-mind)
  2773.             gr += '"dst.%s" [label = "%s", shape=triangle, fillcolor="#0000ff", style=filled, fixedsize=1, height=%.2f, width=%.2f];\n' % (`d`,`d`,n,n)
  2774.  
  2775.         gr += "###\n"
  2776.         for s in sl:
  2777.             n,l = sl[s]
  2778.             for e in l:
  2779.                 gr += ' "src.%s" -> "evt.%s";\n' % (`s`,`e`) 
  2780.         for e in el:
  2781.             n,l = el[e]
  2782.             for d in l:
  2783.                 gr += ' "evt.%s" -> "dst.%s";\n' % (`e`,`d`) 
  2784.             
  2785.         gr += "}"
  2786.         open("/tmp/aze","w").write(gr)
  2787.         do_graph(gr, **kargs)
  2788.         
  2789.  
  2790.         
  2791.     def timeskew_graph(self, ip, **kargs):
  2792.         """Tries to graph the timeskew between the timestamps and real time for a given ip"""
  2793.         res = map(lambda x: self._elt2pkt(x), self.res)
  2794.         b = filter(lambda x:x.haslayer(IP) and x.getlayer(IP).src == ip and x.haslayer(TCP), res)
  2795.         c = []
  2796.         for p in b:
  2797.             opts = p.getlayer(TCP).options
  2798.             for o in opts:
  2799.                 if o[0] == "Timestamp":
  2800.                     c.append((p.time,o[1][0]))
  2801.         if not c:
  2802.             warning("No timestamps found in packet list")
  2803.             return
  2804.         d = map(lambda (x,y): (x%2000,((x-c[0][0])-((y-c[0][1])/1000.0))),c)
  2805.         g = Gnuplot.Gnuplot()
  2806.         g.plot(Gnuplot.Data(d,**kargs))
  2807.         return g
  2808.         
  2809.     def _dump_document(self, **kargs):
  2810.         d = pyx.document.document()
  2811.         l = len(self.res)
  2812.         for i in range(len(self.res)):
  2813.             elt = self.res[i]
  2814.             c = self._elt2pkt(elt).canvas_dump(**kargs)
  2815.             cbb = c.bbox()
  2816.             c.text(cbb.left(),cbb.top()+1,r"\font\cmssfont=cmss12\cmssfont{Frame %i/%i}" % (i,l),[pyx.text.size.LARGE])
  2817.             if conf.verb >= 2:
  2818.                 os.write(1,".")
  2819.             d.append(pyx.document.page(c, paperformat=pyx.document.paperformat.A4,
  2820.                                        margin=1*pyx.unit.t_cm,
  2821.                                        fittosize=1))
  2822.         return d
  2823.                      
  2824.                  
  2825.  
  2826.     def psdump(self, filename = None, **kargs):
  2827.         """Creates a multipage poscript file with a psdump of every packet
  2828.         filename: name of the file to write to. If empty, a temporary file is used and
  2829.                   conf.prog.psreader is called"""
  2830.         d = self._dump_document(**kargs)
  2831.         if filename is None:
  2832.             filename = "/tmp/scapy.psd.%i" % os.getpid()
  2833.             d.writePSfile(filename)
  2834.             os.system("%s %s.ps &" % (conf.prog.psreader,filename))
  2835.         else:
  2836.             d.writePSfile(filename)
  2837.         print
  2838.         
  2839.     def pdfdump(self, filename = None, **kargs):
  2840.         """Creates a PDF file with a psdump of every packet
  2841.         filename: name of the file to write to. If empty, a temporary file is used and
  2842.                   conf.prog.pdfreader is called"""
  2843.         d = self._dump_document(**kargs)
  2844.         if filename is None:
  2845.             filename = "/tmp/scapy.psd.%i" % os.getpid()
  2846.             d.writePDFfile(filename)
  2847.             os.system("%s %s.pdf &" % (conf.prog.pdfreader,filename))
  2848.         else:
  2849.             d.writePDFfile(filename)
  2850.         print
  2851.  
  2852.     def sr(self,multi=0):
  2853.         """sr([multi=1]) -> (SndRcvList, PacketList)
  2854.         Matches packets in the list and return ( (matched couples), (unmatched packets) )"""
  2855.         remain = self.res[:]
  2856.         sr = []
  2857.         i = 0
  2858.         while i < len(remain):
  2859.             s = remain[i]
  2860.             j = i
  2861.             while j < len(remain)-1:
  2862.                 j += 1
  2863.                 r = remain[j]
  2864.                 if r.answers(s):
  2865.                     sr.append((s,r))
  2866.                     if multi:
  2867.                         remain[i]._answered=1
  2868.                         remain[j]._answered=2
  2869.                         continue
  2870.                     del(remain[j])
  2871.                     del(remain[i])
  2872.                     i -= 1
  2873.                     break
  2874.             i += 1
  2875.             print i, len(remain)
  2876.         if multi:
  2877.             remain = filter(lambda x:not hasattr(x,"_answered"), remain)
  2878.         return SndRcvList(sr),PacketList(remain)
  2879.         
  2880.  
  2881.  
  2882.         
  2883.  
  2884.  
  2885. class Dot11PacketList(PacketList):
  2886.     def __init__(self, res, name="Dot11List", stats=None):
  2887.         if stats is None:
  2888.             stats = [Dot11WEP, Dot11Beacon, UDP, ICMP, TCP]
  2889.  
  2890.         PacketList.__init__(self, res, name, stats)
  2891.     def toEthernet(self):
  2892.         data = map(lambda x:x.getlayer(Dot11), filter(lambda x : x.haslayer(Dot11) and x.type == 2, self.res))
  2893.         r2 = []
  2894.         for p in data:
  2895.             q = p.copy()
  2896.             q.unwep()
  2897.             r2.append(Ether()/q.payload.payload.payload) #Dot11/LLC/SNAP/IP
  2898.         return PacketList(r2,name="Ether from %s"%self.listname)
  2899.         
  2900.         
  2901.  
  2902. class SndRcvList(PacketList):
  2903.     def __init__(self, res, name="Results", stats=None):
  2904.         PacketList.__init__(self, res, name, stats)
  2905.     def _elt2pkt(self, elt):
  2906.         return elt[1]
  2907.     def _elt2sum(self, elt):
  2908.         return "%s ==> %s" % (elt[0].summary(),elt[1].summary()) 
  2909.  
  2910.  
  2911. class ARPingResult(SndRcvList):
  2912.     def __init__(self, res, name="ARPing", stats=None):
  2913.         PacketList.__init__(self, res, name, stats)
  2914.  
  2915.     def show(self):
  2916.         for s,r in self.res:
  2917.             print r.sprintf("%Ether.src% %ARP.psrc%")
  2918.  
  2919.  
  2920.  
  2921.  
  2922. class TracerouteResult(SndRcvList):
  2923.     def __init__(self, res, name="Traceroute", stats=None):
  2924.         PacketList.__init__(self, res, name, stats)
  2925.         self.graphdef = None
  2926.         self.graphASN = 0
  2927.         self.padding = 0
  2928.         self.hloc = None
  2929.         self.nloc = None
  2930.  
  2931.     def show(self):
  2932.         return self.make_table(lambda (s,r): (s.sprintf("%IP.dst%:{TCP:tcp%ir,TCP.dport%}{UDP:udp%ir,UDP.dport%}{ICMP:ICMP}"),
  2933.                                               s.ttl,
  2934.                                               r.sprintf("%-15s,IP.src% {TCP:%TCP.flags%}{ICMP:%ir,ICMP.type%}")))
  2935.  
  2936.  
  2937.     def get_trace(self):
  2938.         trace = {}
  2939.         for s,r in self.res:
  2940.             if IP not in s:
  2941.                 continue
  2942.             d = s[IP].dst
  2943.             if d not in trace:
  2944.                 trace[d] = {}
  2945.             trace[d][s[IP].ttl] = r[IP].src, ICMP not in r
  2946.         for k in trace.values():
  2947.             m = filter(lambda x:k[x][1], k.keys())
  2948.             if not m:
  2949.                 continue
  2950.             m = min(m)
  2951.             for l in k.keys():
  2952.                 if l > m:
  2953.                     del(k[l])
  2954.         return trace
  2955.  
  2956.     def trace3D(self):
  2957.         """Give a 3D representation of the traceroute.
  2958.         right button: rotate the scene
  2959.         middle button: zoom
  2960.         left button: move the scene
  2961.         left button on a ball: toggle IP displaying
  2962.         ctrl-left button on a ball: scan ports 21,22,23,25,80 and 443 and display the result"""
  2963.         trace = self.get_trace()
  2964.         import visual
  2965.  
  2966.         class IPsphere(visual.sphere):
  2967.             def __init__(self, ip, **kargs):
  2968.                 visual.sphere.__init__(self, **kargs)
  2969.                 self.ip=ip
  2970.                 self.label=None
  2971.                 self.setlabel(self.ip)
  2972.             def setlabel(self, txt,visible=None):
  2973.                 if self.label is not None:
  2974.                     if visible is None:
  2975.                         visible = self.label.visible
  2976.                     self.label.visible = 0
  2977.                 elif visible is None:
  2978.                     visible=0
  2979.                 self.label=visual.label(text=txt, pos=self.pos, space=self.radius, xoffset=10, yoffset=20, visible=visible)
  2980.             def action(self):
  2981.                 self.label.visible ^= 1
  2982.  
  2983.         visual.scene = visual.display()
  2984.         visual.scene.exit_on_close(0)
  2985.         start = visual.box()
  2986.         rings={}
  2987.         tr3d = {}
  2988.         for i in trace:
  2989.             tr = trace[i]
  2990.             tr3d[i] = []
  2991.             ttl = tr.keys()
  2992.             for t in range(1,max(ttl)+1):
  2993.                 if t not in rings:
  2994.                     rings[t] = []
  2995.                 if t in tr:
  2996.                     if tr[t] not in rings[t]:
  2997.                         rings[t].append(tr[t])
  2998.                     tr3d[i].append(rings[t].index(tr[t]))
  2999.                 else:
  3000.                     rings[t].append(("unk",-1))
  3001.                     tr3d[i].append(len(rings[t])-1)
  3002.         for t in rings:
  3003.             r = rings[t]
  3004.             l = len(r)
  3005.             for i in range(l):
  3006.                 if r[i][1] == -1:
  3007.                     col = (0.75,0.75,0.75)
  3008.                 elif r[i][1]:
  3009.                     col = visual.color.green
  3010.                 else:
  3011.                     col = visual.color.blue
  3012.                 
  3013.                 s = IPsphere(pos=((l-1)*visual.cos(2*i*visual.pi/l),(l-1)*visual.sin(2*i*visual.pi/l),2*t),
  3014.                              ip = r[i][0],
  3015.                              color = col)
  3016.                 for trlst in tr3d.values():
  3017.                     if t <= len(trlst):
  3018.                         if trlst[t-1] == i:
  3019.                             trlst[t-1] = s
  3020.         forecol = colgen(0.625, 0.4375, 0.25, 0.125)
  3021.         for trlst in tr3d.values():
  3022.             col = forecol.next()
  3023.             start = (0,0,0)
  3024.             for ip in trlst:
  3025.                 visual.cylinder(pos=start,axis=ip.pos-start,color=col,radius=0.2)
  3026.                 start = ip.pos
  3027.         
  3028.         movcenter=None
  3029.         while 1:
  3030.             if visual.scene.kb.keys:
  3031.                 k = visual.scene.kb.getkey()
  3032.                 if k == "esc":
  3033.                     break
  3034.             if visual.scene.mouse.events:
  3035.                 ev = visual.scene.mouse.getevent()
  3036.                 if ev.press == "left":
  3037.                     o = ev.pick
  3038.                     if o:
  3039.                         if ev.ctrl:
  3040.                             if o.ip == "unk":
  3041.                                 continue
  3042.                             savcolor = o.color
  3043.                             o.color = (1,0,0)
  3044.                             a,b=sr(IP(dst=o.ip)/TCP(dport=[21,22,23,25,80,443]),timeout=2)
  3045.                             o.color = savcolor
  3046.                             if len(a) == 0:
  3047.                                 txt = "%s:\nno results" % o.ip
  3048.                             else:
  3049.                                 txt = "%s:\n" % o.ip
  3050.                                 for s,r in a:
  3051.                                     txt += r.sprintf("{TCP:%IP.src%:%TCP.sport% %TCP.flags%}{TCPerror:%IPerror.dst%:%TCPerror.dport% %IP.src% %ir,ICMP.type%}\n")
  3052.                             o.setlabel(txt, visible=1)
  3053.                         else:
  3054.                             if hasattr(o, "action"):
  3055.                                 o.action()
  3056.                 elif ev.drag == "left":
  3057.                     movcenter = ev.pos
  3058.                 elif ev.drop == "left":
  3059.                     movcenter = None
  3060.             if movcenter:
  3061.                 visual.scene.center -= visual.scene.mouse.pos-movcenter
  3062.                 movcenter = visual.scene.mouse.pos
  3063.                 
  3064.                 
  3065.     def world_trace(self):
  3066.         ips = {}
  3067.         rt = {}
  3068.         ports_done = {}
  3069.         for s,r in self.res:
  3070.             ips[r.src] = None
  3071.             if s.haslayer(TCP) or s.haslayer(UDP):
  3072.                 trace_id = (s.src,s.dst,s.proto,s.dport)
  3073.             elif s.haslayer(ICMP):
  3074.                 trace_id = (s.src,s.dst,s.proto,s.type)
  3075.             else:
  3076.                 trace_id = (s.src,s.dst,s.proto,0)
  3077.             trace = rt.get(trace_id,{})
  3078.             if not r.haslayer(ICMP) or r.type != 11:
  3079.                 if ports_done.has_key(trace_id):
  3080.                     continue
  3081.                 ports_done[trace_id] = None
  3082.             trace[s.ttl] = r.src
  3083.             rt[trace_id] = trace
  3084.  
  3085.         trt = {}
  3086.         for trace_id in rt:
  3087.             trace = rt[trace_id]
  3088.             loctrace = []
  3089.             for i in range(max(trace.keys())):
  3090.                 ip = trace.get(i,None)
  3091.                 if ip is None:
  3092.                     continue
  3093.                 loc = locate_ip(ip)
  3094.                 if loc is None:
  3095.                     continue
  3096. #                loctrace.append((ip,loc)) # no labels yet
  3097.                 loctrace.append(loc)
  3098.             if loctrace:
  3099.                 trt[trace_id] = loctrace
  3100.  
  3101.         tr = map(lambda x: Gnuplot.Data(x,with="lines"), trt.values())
  3102.         g = Gnuplot.Gnuplot()
  3103.         world = Gnuplot.File(conf.gnuplot_world,with="lines")
  3104.         g.plot(world,*tr)
  3105.         return g
  3106.  
  3107.     def make_graph(self,ASN,padding):
  3108.         self.graphASN = ASN
  3109.         self.graphpadding = padding
  3110.         ips = {}
  3111.         rt = {}
  3112.         ports = {}
  3113.         ports_done = {}
  3114.         for s,r in self.res:
  3115.             ips[r.src] = None
  3116.             if s.haslayer(TCP) or s.haslayer(UDP):
  3117.                 trace_id = (s.src,s.dst,s.proto,s.dport)
  3118.             elif s.haslayer(ICMP):
  3119.                 trace_id = (s.src,s.dst,s.proto,s.type)
  3120.             else:
  3121.                 trace_id = (s.src,s.dst,s.proto,0)
  3122.             trace = rt.get(trace_id,{})
  3123.             if not r.haslayer(ICMP) or r.type != 11:
  3124.                 if ports_done.has_key(trace_id):
  3125.                     continue
  3126.                 ports_done[trace_id] = None
  3127.                 p = ports.get(r.src,[])
  3128.                 if r.haslayer(TCP):
  3129.                     p.append(r.sprintf("<T%ir,TCP.sport%> %TCP.sport%: %TCP.flags%"))
  3130.                     trace[s.ttl] = r.sprintf('"%IP.src%":T%ir,TCP.sport%')
  3131.                 elif r.haslayer(UDP):
  3132.                     p.append(r.sprintf("<U%ir,UDP.sport%> %UDP.sport%"))
  3133.                     trace[s.ttl] = r.sprintf('"%IP.src%":U%ir,UDP.sport%')
  3134.                 elif r.haslayer(ICMP):
  3135.                     p.append(r.sprintf("<I%ir,ICMP.type%> ICMP %ICMP.type%"))
  3136.                     trace[s.ttl] = r.sprintf('"%IP.src%":I%ir,ICMP.type%')
  3137.                 else:
  3138.                     p.append(r.sprintf("<P%ir,IP.proto> IP %IP.proto%"))
  3139.                     trace[s.ttl] = r.sprintf('"%IP.src%":P%ir,IP.proto%')                    
  3140.                 ports[r.src] = p
  3141.             else:
  3142.                 trace[s.ttl] = r.sprintf('"%IP.src%"')
  3143.             rt[trace_id] = trace
  3144.     
  3145.         # Fill holes with unk%i nodes
  3146.         unk = 0
  3147.         blackholes = []
  3148.         bhip = {}
  3149.         for rtk in rt:
  3150.             trace = rt[rtk]
  3151.             k = trace.keys()
  3152.             for n in range(min(k), max(k)):
  3153.                 if not trace.has_key(n):
  3154.                     trace[n] = "unk%i" % unk
  3155.                     unk += 1
  3156.             if not ports_done.has_key(rtk):
  3157.                 if rtk[2] == 1: #ICMP
  3158.                     bh = "%s %i" % (rtk[1],rtk[3])
  3159.                 elif rtk[2] == 6: #TCP
  3160.                     bh = "%s:%i/tcp" % (rtk[1],rtk[3])
  3161.                 elif rtk[2] == 17: #UDP                    
  3162.                     bh = '%s:%i/udp' % (rtk[1],rtk[3])
  3163.                 else:
  3164.                     bh = '%s,proto %i' % (rtk[1],rtk[2]) 
  3165.                 ips[bh] = None
  3166.                 bhip[rtk[1]] = bh
  3167.                 bh = '"%s"' % bh
  3168.                 trace[max(k)+1] = bh
  3169.                 blackholes.append(bh)
  3170.     
  3171.         # Find AS numbers
  3172.     
  3173.     
  3174.         def getASNlist_radb(list):
  3175.             
  3176.             def parseWhois(x):
  3177.                 asn,desc = None,""
  3178.                 for l in x.splitlines():
  3179.                     if not asn and l.startswith("origin:"):
  3180.                         asn = l[7:].strip()
  3181.                     if l.startswith("descr:"):
  3182.                         if desc:
  3183.                             desc += r"\n"
  3184.                         desc += l[6:].strip()
  3185.                     if asn is not None and desc:
  3186.                         break
  3187.                 return asn,desc.strip()
  3188.  
  3189.             ASNlist = []
  3190.             s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  3191.             s.connect(("whois.ra.net",43))
  3192.             for ip in list:
  3193.                 s.send("-k %s\n" % ip)
  3194.                 asn,desc = parseWhois(s.recv(8192))
  3195.                 ASNlist.append((ip,asn,desc))
  3196.             return ASNlist
  3197.         
  3198.         def getASNlist_cymru(list):
  3199.             ASNlist = []
  3200.             s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  3201.             s.connect(("whois.cymru.com",43))
  3202.             s.send("begin\r\n"+"\r\n".join(list)+"\r\nend\r\n")
  3203.             r = ""
  3204.             while 1:
  3205.                 l = s.recv(8192)
  3206.                 if l == "":
  3207.                     break
  3208.                 r += l
  3209.             s.close()
  3210.             for l in r.splitlines()[1:]:
  3211.                 asn,ip,desc = map(str.strip, l.split("|"))
  3212.                 if asn == "NA":
  3213.                     continue
  3214.                 asn = int(asn)
  3215.                 ASNlist.append((ip,asn,desc))
  3216.             return ASNlist
  3217.                 
  3218.  
  3219.         ASN_query_list = dict.fromkeys(map(lambda x:x.split(":")[0],ips)).keys()
  3220.         if ASN in [1,2]:
  3221.             ASNlist = getASNlist_cymru(ASN_query_list)
  3222.         elif ASN == 3:
  3223.             ASNlist = getASNlist_radb(ASN_query_list)
  3224.         else:
  3225.             ASNlist = []
  3226.             
  3227.  
  3228.         if ASN == 1:
  3229.             ASN_ans_list = map(lambda x:x[0], ASNlist)
  3230.             ASN_remain_list = filter(lambda x: x not in ASN_ans_list, ASN_query_list)
  3231.             if ASN_remain_list:
  3232.                 ASNlist += getASNlist_radb(ASN_remain_list)
  3233.         
  3234.             
  3235.     
  3236.         ASNs = {}
  3237.         ASDs = {}
  3238.         for ip,asn,desc, in ASNlist:
  3239.             if asn is None:
  3240.                 continue
  3241.             iplist = ASNs.get(asn,[])
  3242.             if ip in bhip:
  3243.                 if ip in ports:
  3244.                     iplist.append(ip)
  3245.                 iplist.append(bhip[ip])
  3246.             else:
  3247.                 iplist.append(ip)
  3248.             ASNs[asn] = iplist
  3249.             ASDs[asn] = desc
  3250.     
  3251.     
  3252.         backcolorlist=colgen("60","86","ba","ff")
  3253.         forecolorlist=colgen("a0","70","40","20")
  3254.     
  3255.         s = "digraph trace {\n"
  3256.     
  3257.         s += "\n\tnode [shape=ellipse,color=black,style=solid];\n\n"
  3258.     
  3259.         s += "\n#ASN clustering\n"
  3260.         for asn in ASNs:
  3261.             s += '\tsubgraph cluster_%s {\n' % asn
  3262.             col = backcolorlist.next()
  3263.             s += '\t\tcolor="#%s%s%s";' % col
  3264.             s += '\t\tnode [fillcolor="#%s%s%s",style=filled];' % col
  3265.             s += '\t\tfontsize = 10;'
  3266.             s += '\t\tlabel = "%s\\n[%s]"\n' % (asn,ASDs[asn])
  3267.             for ip in ASNs[asn]:
  3268.     
  3269.                 s += '\t\t"%s";\n'%ip
  3270.             s += "\t}\n"
  3271.     
  3272.     
  3273.     
  3274.     
  3275.         s += "#endpoints\n"
  3276.         for p in ports:
  3277.             s += '\t"%s" [shape=record,color=black,fillcolor=green,style=filled,label="%s|%s"];\n' % (p,p,"|".join(ports[p]))
  3278.     
  3279.         s += "\n#Blackholes\n"
  3280.         for bh in blackholes:
  3281.             s += '\t%s [shape=octagon,color=black,fillcolor=red,style=filled];\n' % bh
  3282.  
  3283.         if padding:
  3284.             s += "\n#Padding\n"
  3285.             pad={}
  3286.             for snd,rcv in self.res:
  3287.                 if rcv.src not in ports and rcv.haslayer(Padding):
  3288.                     p = rcv.getlayer(Padding).load
  3289.                     if p != "\x00"*len(p):
  3290.                         pad[rcv.src]=None
  3291.             for rcv in pad:
  3292.                 s += '\t"%s" [shape=triangle,color=black,fillcolor=red,style=filled];\n' % rcv
  3293.     
  3294.     
  3295.             
  3296.         s += "\n\tnode [shape=ellipse,color=black,style=solid];\n\n"
  3297.     
  3298.     
  3299.         for rtk in rt:
  3300.             s += "#---[%s\n" % `rtk`
  3301.             s += '\t\tedge [color="#%s%s%s"];\n' % forecolorlist.next()
  3302.             trace = rt[rtk]
  3303.             k = trace.keys()
  3304.             for n in range(min(k), max(k)):
  3305.                 s += '\t%s ->\n' % trace[n]
  3306.             s += '\t%s;\n' % trace[max(k)]
  3307.     
  3308.         s += "}\n";
  3309.         self.graphdef = s
  3310.     
  3311.     def graph(self, ASN=1, padding=0, **kargs):
  3312.         """x.graph(ASN=1, other args):
  3313.         ASN=0 : no clustering
  3314.         ASN=1 : use whois.cymru.net AS clustering
  3315.         ASN=2 : use whois.ra.net AS clustering
  3316.         graph: GraphViz graph description
  3317.         type: output type (svg, ps, gif, jpg, etc.), passed to dot's "-T" option
  3318.         target: filename or redirect. Defaults pipe to Imagemagick's display program
  3319.         prog: which graphviz program to use"""
  3320.         if (self.graphdef is None or
  3321.             self.graphASN != ASN or
  3322.             self.graphpadding != padding):
  3323.             self.make_graph(ASN,padding)
  3324.  
  3325.         do_graph(self.graphdef, **kargs)
  3326.  
  3327.  
  3328.         
  3329.     
  3330. ############
  3331. ## Fields ##
  3332. ############
  3333.  
  3334. class Field:
  3335.     islist=0
  3336.     def __init__(self, name, default, fmt="H"):
  3337.         self.name = name
  3338.         if fmt[0] in "@=<>!":
  3339.             self.fmt = fmt
  3340.         else:
  3341.             self.fmt = "!"+fmt
  3342.         self.default = self.any2i(None,default)
  3343.         self.sz = struct.calcsize(self.fmt)
  3344.  
  3345.     def h2i(self, pkt, x):
  3346.         return x
  3347.     def i2h(self, pkt, x):
  3348.         return x
  3349.     def m2i(self, pkt, x):
  3350.         return x
  3351.     def i2m(self, pkt, x):
  3352.         if x is None:
  3353.             x = 0
  3354.         return x
  3355.     def any2i(self, pkt, x):
  3356.         return x
  3357.     def i2repr(self, pkt, x):
  3358.     if x is None:
  3359.         x = 0
  3360.         return repr(self.i2h(pkt,x))
  3361.     def addfield(self, pkt, s, val):
  3362.         return s+struct.pack(self.fmt, self.i2m(pkt,val))
  3363.     def getfield(self, pkt, s):
  3364.         return  s[self.sz:], self.m2i(pkt, struct.unpack(self.fmt, s[:self.sz])[0])
  3365.     def do_copy(self, x):
  3366.         if hasattr(x, "copy"):
  3367.             return x.copy()
  3368.         elif type(x) is list:
  3369.             return x[:]
  3370.         else:
  3371.             return x
  3372.     def __eq__(self, other):
  3373.         return self.name == other
  3374.     def __hash__(self):
  3375.         return hash(self.name)
  3376.     def __repr__(self):
  3377.         return self.name
  3378.     def copy(self):
  3379.         return copy.deepcopy(self)
  3380.     def randval(self):
  3381.         fmtt = self.fmt[-1]
  3382.         if fmtt in "BHIQ":
  3383.             return {"B":RandByte,"H":RandShort,"I":RandInt, "Q":RandLong}[fmtt]()
  3384.         elif fmtt == "s":
  3385.             if self.fmt[0] in "0123456789":
  3386.                 l = int(self.fmt[:-1])
  3387.             else:
  3388.                 l = int(self.fmt[1:-1])
  3389.             return RandBin(l)
  3390.         else:
  3391.             warning("no random class for [%s] (fmt=%s)." % (self.name, self.fmt))
  3392.             
  3393.  
  3394.         
  3395.  
  3396.  
  3397. class Emph:
  3398.     fld = ""
  3399.     def __init__(self, fld):
  3400.         self.fld = fld
  3401.     def __getattr__(self, attr):
  3402.         return getattr(self.fld,attr)
  3403.  
  3404.  
  3405. class ConditionalField:
  3406.     def __init__(self, fld, fldlst, cond):
  3407.         self.fld = fld
  3408.         self.fldlst = fldlst
  3409.         self.cond = cond
  3410.     def _evalcond(self,pkt):
  3411.         if type(self.fldlst) is list or type(self.fldlst) is tuple:
  3412.             res = map(lambda x,pkt=pkt:getattr(pkt,x), self.fldlst)
  3413.         else:
  3414.             res = getattr(pkt, self.fldlst)
  3415.         return self.cond(res)
  3416.         
  3417.     def getfield(self, pkt, s):
  3418.         if self._evalcond(pkt):
  3419.             return self.fld.getfield(pkt,s)
  3420.         else:
  3421.             return s,None
  3422.         
  3423.     def addfield(self, pkt, s, val):
  3424.         if self._evalcond(pkt):
  3425.             return self.fld.addfield(pkt,s,val)
  3426.         else:
  3427.             return s
  3428.     def __getattr__(self, attr):
  3429.         return getattr(self.fld,attr)
  3430.         
  3431.  
  3432. class MACField(Field):
  3433.     def __init__(self, name, default):
  3434.         Field.__init__(self, name, default, "6s")
  3435.     def i2m(self, pkt, x):
  3436.         if x is None:
  3437.             x="00:00:00:00:00:00"
  3438.         return mac2str(x)
  3439.     def m2i(self, pkt, x):
  3440.         return str2mac(x)
  3441.     def any2i(self, pkt, x):
  3442.         if type(x) is str and len(x) is 6:
  3443.             x = self.m2i(pkt, x)
  3444.         return x
  3445.     def i2repr(self, pkt, x):
  3446.         return self.i2h(pkt, x)
  3447.     def randval(self):
  3448.         return RandMAC()
  3449.  
  3450. class DestMACField(MACField):
  3451.     def __init__(self, name):
  3452.         MACField.__init__(self, name, None)
  3453.     def i2h(self, pkt, x):
  3454.         if x is None:
  3455.             dstip = None
  3456.             if isinstance(pkt.payload, IPv6):
  3457.                 dstip = pkt.payload.dst            
  3458.             elif isinstance(pkt.payload, IP):
  3459.                 dstip = pkt.payload.dst
  3460.             elif isinstance(pkt.payload, ARP):
  3461.                 dstip = pkt.payload.pdst
  3462.             if isinstance(dstip, Gen):
  3463.                 dstip = dstip.__iter__().next()
  3464.             if dstip is not None:
  3465.                 if isinstance(pkt.payload, IPv6):
  3466.                     x = getmacbyip6(dstip)
  3467.                 else:    
  3468.                     x = getmacbyip(dstip)
  3469.             if x is None:
  3470.                 x = "ff:ff:ff:ff:ff:ff"
  3471.                 warning("Mac address to reach %s not found\n"%dstip)
  3472.         return MACField.i2h(self, pkt, x)
  3473.     def i2m(self, pkt, x):
  3474.         return MACField.i2m(self, pkt, self.i2h(pkt, x))
  3475.         
  3476. class SourceMACField(MACField):
  3477.     def __init__(self, name):
  3478.         MACField.__init__(self, name, None)
  3479.     def i2h(self, pkt, x):
  3480.         if x is None:
  3481.             dstip = None
  3482.             if isinstance(pkt.payload, IPv6):
  3483.                 dstip = pkt.payload.dst
  3484.             elif isinstance(pkt.payload, IP):
  3485.                 dstip = pkt.payload.dst
  3486.             elif isinstance(pkt.payload, ARP):
  3487.                 dstip = pkt.payload.pdst
  3488.             if isinstance(dstip, Gen):
  3489.                 dstip = dstip.__iter__().next()
  3490.             if dstip is not None:
  3491.                 if isinstance(pkt.payload, IPv6):
  3492.                     iff,a,nh = conf.route6.route(dstip)
  3493.                 else:
  3494.                     iff,a,gw = conf.route.route(dstip)
  3495.                 x = get_if_hwaddr(iff)
  3496.                 if x is None:
  3497.                     x = "00:00:00:00:00:00"
  3498.         return MACField.i2h(self, pkt, x)
  3499.     def i2m(self, pkt, x):
  3500.         return MACField.i2m(self, pkt, self.i2h(pkt, x))
  3501.         
  3502. class ARPSourceMACField(MACField):
  3503.     def __init__(self, name):
  3504.         MACField.__init__(self, name, None)
  3505.     def i2h(self, pkt, x):
  3506.         if x is None:
  3507.             dstip = pkt.pdst
  3508.             if isinstance(dstip, Gen):
  3509.                 dstip = dstip.__iter__().next()
  3510.             if dstip is not None:
  3511.                 iff,a,gw = conf.route.route(dstip)
  3512.                 x = get_if_hwaddr(iff)
  3513.                 if x is None:
  3514.                     x = "00:00:00:00:00:00"
  3515.         return MACField.i2h(self, pkt, x)
  3516.     def i2m(self, pkt, x):
  3517.         return MACField.i2m(self, pkt, self.i2h(pkt, x))
  3518.  
  3519. class Dot11AddrMACField(MACField):
  3520.     def is_applicable(self, pkt):
  3521.         return 1
  3522.     def addfield(self, pkt, s, val):
  3523.         if self.is_applicable(pkt):
  3524.             return MACField.addfield(self, pkt, s, val)
  3525.         else:
  3526.             return s        
  3527.     def getfield(self, pkt, s):
  3528.         if self.is_applicable(pkt):
  3529.             return MACField.getfield(self, pkt, s)
  3530.         else:
  3531.             return s,None
  3532.  
  3533. class Dot11Addr2MACField(Dot11AddrMACField):
  3534.     def is_applicable(self, pkt):
  3535.         if pkt.type == 1:
  3536.             return pkt.subtype in [ 0xb, 0xa, 0xe, 0xf] # RTS, PS-Poll, CF-End, CF-End+CF-Ack
  3537.         return 1
  3538.  
  3539. class Dot11Addr3MACField(Dot11AddrMACField):
  3540.     def is_applicable(self, pkt):
  3541.         if pkt.type in [0,2]:
  3542.             return 1
  3543.         return 0
  3544.  
  3545. class Dot11Addr4MACField(Dot11AddrMACField):
  3546.     def is_applicable(self, pkt):
  3547.         if pkt.type == 2:
  3548.             if pkt.FCfield & 0x3 == 0x3: # To-DS and From-DS are set
  3549.                 return 1
  3550.         return 0
  3551.     
  3552. class IPField(Field):
  3553.     def __init__(self, name, default):
  3554.         Field.__init__(self, name, default, "4s")
  3555.     def h2i(self, pkt, x):
  3556.         if type(x) is str:
  3557.             try:
  3558.                 inet_aton(x)
  3559.             except socket.error:
  3560.                 x = Net(x)
  3561.         elif type(x) is list:
  3562.             x = map(Net, x)
  3563.         return x
  3564.     def i2m(self, pkt, x):
  3565.         return inet_aton(x)
  3566.     def m2i(self, pkt, x):
  3567.         return inet_ntoa(x)
  3568.     def any2i(self, pkt, x):
  3569. #        if type(x) is str and len(x) == 4:
  3570. #            x = self.m2i(pkt, x)
  3571.         return self.h2i(pkt,x)
  3572.     def i2repr(self, pkt, x):
  3573.         return self.i2h(pkt, x)
  3574.     def randval(self):
  3575.         return RandIP()
  3576.  
  3577. class SourceIPField(IPField):
  3578.     def __init__(self, name, dstname):
  3579.         IPField.__init__(self, name, None)
  3580.         self.dstname = dstname
  3581.     def i2m(self, pkt, x):
  3582.         if x is None:
  3583.             iff,x,gw = conf.route.route(getattr(pkt,self.dstname))
  3584.         return IPField.i2m(self, pkt, x)
  3585.     def i2h(self, pkt, x):
  3586.         if x is None:
  3587.             dst=getattr(pkt,self.dstname)
  3588.             if isinstance(dst,Gen):
  3589.                 r = map(conf.route.route, dst)
  3590.                 r.sort()
  3591.                 if r[0] == r[-1]:
  3592.                     x=r[0][1]
  3593.                 else:
  3594.                     warning("More than one possible route for %s"%repr(dst))
  3595.                     return None
  3596.             else:
  3597.                 iff,x,gw = conf.route.route(dst)
  3598.         return IPField.i2h(self, pkt, x)
  3599.  
  3600.     
  3601.  
  3602.  
  3603. class ByteField(Field):
  3604.     def __init__(self, name, default):
  3605.         Field.__init__(self, name, default, "B")
  3606.         
  3607. class XByteField(ByteField):
  3608.     def i2repr(self, pkt, x):
  3609.     if x is None:
  3610.         x = 0
  3611.         return hex(self.i2h(pkt, x))
  3612.  
  3613. class X3BytesField(XByteField):
  3614.     def __init__(self, name, default):
  3615.         Field.__init__(self, name, default, "I")
  3616.     def addfield(self, pkt, s, val):
  3617.         return s+struct.pack(self.fmt, self.i2m(pkt,val))[:3]
  3618.     def getfield(self, pkt, s):
  3619.         return  s[3:], self.m2i(pkt, struct.unpack(self.fmt, "\x00"+s[:3])[0])
  3620.  
  3621.  
  3622. class ShortField(Field):
  3623.     def __init__(self, name, default):
  3624.         Field.__init__(self, name, default, "H")
  3625.  
  3626. class LEShortField(Field):
  3627.     def __init__(self, name, default):
  3628.         Field.__init__(self, name, default, "@H")
  3629.  
  3630. class XShortField(ShortField):
  3631.     def i2repr(self, pkt, x):
  3632.     if x is None:
  3633.         x = 0
  3634.         return hex(self.i2h(pkt, x))
  3635.  
  3636.  
  3637. class IntField(Field):
  3638.     def __init__(self, name, default):
  3639.         Field.__init__(self, name, default, "I")
  3640.  
  3641. class SignedIntField(Field):
  3642.     def __init__(self, name, default):
  3643.         Field.__init__(self, name, default, "i")
  3644.  
  3645. class LEIntField(Field):
  3646.     def __init__(self, name, default):
  3647.         Field.__init__(self, name, default, "@I")
  3648.  
  3649. class LESignedIntField(Field):
  3650.     def __init__(self, name, default):
  3651.         Field.__init__(self, name, default, "@i")
  3652.  
  3653. class XIntField(IntField):
  3654.     def i2repr(self, pkt, x):
  3655.     if x is None:
  3656.         x = 0
  3657.         return hex(self.i2h(pkt, x))
  3658.  
  3659.  
  3660. class LongField(Field):
  3661.     def __init__(self, name, default):
  3662.         Field.__init__(self, name, default, "Q")
  3663.  
  3664. class XLongField(LongField):
  3665.     def i2repr(self, pkt, x):
  3666.     if x is None:
  3667.         x = 0
  3668.         return hex(self.i2h(pkt, x))
  3669.  
  3670.  
  3671. class StrField(Field):
  3672.     def __init__(self, name, default, fmt="H", remain=0):
  3673.         Field.__init__(self,name,default,fmt)
  3674.         self.remain = remain
  3675.     def i2m(self, pkt, x):
  3676.         if x is None:
  3677.             x = ""
  3678.         return x
  3679.     def addfield(self, pkt, s, val):
  3680.         return s+self.i2m(pkt, val)
  3681.     def getfield(self, pkt, s):
  3682.         if self.remain == 0:
  3683.             return "",self.m2i(pkt, s)
  3684.         else:
  3685.             return s[-self.remain:],self.m2i(pkt, s[:-self.remain])
  3686.     def randval(self):
  3687.         return RandBin(RandNum(0,1200))
  3688.  
  3689. class PacketField(StrField):
  3690.     def __init__(self, name, default, cls):
  3691.         StrField.__init__(self, name, default)
  3692.         self.cls = cls
  3693.     def i2m(self, pkt, i):
  3694.         return str(i)
  3695.     def m2i(self, pkt, m):
  3696.         return self.cls(m)
  3697.     def getfield(self, pkt, s):
  3698.         i = self.m2i(pkt, s)
  3699.         remain = ""
  3700.         if i.haslayer(Padding):
  3701.             r = i.getlayer(Padding)
  3702.             del(r.underlayer.payload)
  3703.             remain = r.load
  3704.         return remain,i
  3705.     
  3706. class PacketLenField(PacketField):
  3707.     def __init__(self, name, default, cls, fld):
  3708.         PacketField.__init__(self, name, default, cls)
  3709.         self.fld = fld
  3710.     def getfield(self, pkt, s):
  3711.         l = getattr(pkt, self.fld)
  3712.         l += pkt.get_field(self.fld).shift
  3713.         i = self.m2i(pkt, s[:l])
  3714.         return s[l:],i
  3715.  
  3716.  
  3717.  
  3718. class StrFixedLenField(StrField):
  3719.     def __init__(self, name, default, length):
  3720.         StrField.__init__(self, name, default)
  3721.         self.length = length
  3722.     def getfield(self, pkt, s):
  3723.         return s[self.length:], self.m2i(pkt,s[:self.length])
  3724.     def addfield(self, pkt, s, val):
  3725.         return s+struct.pack("%is"%self.length,self.i2m(pkt, val))
  3726.     def randval(self):
  3727.         return RandBin(self.length)
  3728.  
  3729. class NetBIOSNameField(StrFixedLenField):
  3730.     def __init__(self, name, default, length=31):
  3731.         StrFixedLenField.__init__(self, name, default, length)
  3732.     def i2m(self, pkt, x):
  3733.         if x is None:
  3734.             x = ""
  3735.         x += " "*(self.length/2)
  3736.         x = x[:(self.length/2)]
  3737.         x = "".join(map(lambda x: chr(0x41+(ord(x)>>4))+chr(0x41+(ord(x)&0xf)), x))
  3738.         x = " "+x
  3739.         return x
  3740.     def m2i(self, pkt, x):
  3741.         x = x.strip("\x00").strip(" ")
  3742.         return "".join(map(lambda x,y: chr((((ord(x)-1)&0xf)<<4)+((ord(y)-1)&0xf)), x[::2],x[1::2]))
  3743.  
  3744. class StrLenField(StrField):
  3745.     def __init__(self, name, default, fld):
  3746.         StrField.__init__(self, name, default)
  3747.         self.fld = fld
  3748.     def getfield(self, pkt, s):
  3749.         l = getattr(pkt, self.fld)
  3750.         # add the shift from the length field
  3751.         f = pkt.get_field(self.fld)
  3752.         if isinstance(f, FieldLenField):
  3753.             l += f.shift
  3754.         return s[l:], self.m2i(pkt,s[:l])
  3755.  
  3756. class FieldListField(Field):
  3757.     islist=1
  3758.     def __init__(self, name, default, cls, fld):
  3759.         self.name = name
  3760.         self.default = default
  3761.         self.cls = cls
  3762.         self.fld = fld
  3763.     def i2m(self, pkt, val):
  3764.         if val is None:
  3765.             val = []
  3766.         return val
  3767.     def addfield(self, pkt, s, val):
  3768.         val = self.i2m(pkt, val)
  3769.         for v in val:
  3770.             s = self.cls.addfield(pkt, s, v)
  3771.         return s
  3772.     def getfield(self, pkt, s):
  3773.         l = getattr(pkt, self.fld)        
  3774.         # add the shift from the length field
  3775.         f = pkt.get_field(self.fld)
  3776.         if isinstance(f, FieldLenField):
  3777.             l += f.shift
  3778.         val = []
  3779.         for i in range(l):
  3780.             s,v = self.cls.getfield(pkt, s)
  3781.             val.append(v)
  3782.         return s, val
  3783.  
  3784. class FieldLenField(Field):
  3785.     def __init__(self, name, default, fld, fmt = "H", shift=0):
  3786.         Field.__init__(self, name, default, fmt)
  3787.         self.fld = fld
  3788.         self.shift = shift
  3789.     def i2m(self, pkt, x):
  3790.         if x is None:
  3791.             f = pkt.get_field(self.fld)
  3792.             v = f.i2m(pkt,getattr(pkt, self.fld))
  3793.             if v is None:
  3794.                 l = 0
  3795.             else:
  3796.                 l = len(v)
  3797.             x = l-self.shift
  3798.         return x
  3799. #    def i2h(self, pkt, x):
  3800. #        if x is None:
  3801. #            f = pkt.fields_desc[pkt.fields_desc.index(self.fld)]
  3802. #            v = f.i2m(pkt,getattr(pkt, self.fld))
  3803. #            x = len(v)+self.shift
  3804. #        return x
  3805.  
  3806. ISAKMPTransformTypes = { "Encryption":    (1, { "DES-CBS"  : 1,
  3807.                                                 "3DES-CBC" : 5, }),
  3808.                          "Hash":          (2, { "MD5": 1,
  3809.                                                 "SHA": 2, }),
  3810.                          "Authentication":(3, { "PSK": 1, }),
  3811.                          "GroupDesc":     (4, { "768MODPgr"  : 1,
  3812.                                                 "1024MODPgr" : 2, }),
  3813.                          "LifeType":      (11,{ "Seconds":1, }),
  3814.                          "LifeDuration":  (12,{}),
  3815.                          }
  3816.  
  3817. ISAKMPTransformNum = {}
  3818. for n in ISAKMPTransformTypes:
  3819.     val = ISAKMPTransformTypes[n]
  3820.     tmp = {}
  3821.     for e in val[1]:
  3822.         tmp[val[1][e]] = e
  3823.     ISAKMPTransformNum[val[0]] = (n,tmp)
  3824. del(n)
  3825. del(e)
  3826. del(tmp)
  3827. del(val)
  3828.  
  3829.  
  3830. class ISAKMPTransformSetField(StrLenField):
  3831.     islist=1
  3832.     def type2num(self, (typ,enc)):
  3833.         if ISAKMPTransformTypes.has_key(typ):
  3834.             val = ISAKMPTransformTypes[typ]
  3835.         else:
  3836.             val = (int(typ),{})
  3837.         if val[1].has_key(enc):
  3838.             enc = val[1][enc]
  3839.         else:
  3840.             enc = int(enc)
  3841.         return ((val[0] | 0x8000L) << 16) | enc
  3842.     def num2type(self, num):
  3843.         typ = (num >> 16) & 0x7fff
  3844.         enc = num & 0xffff
  3845.         val = ISAKMPTransformNum.get(typ,(typ,{}))
  3846.         enc = val[1].get(enc,enc)
  3847.         return (val[0],enc)
  3848.         
  3849.         
  3850.     def i2m(self, pkt, i):
  3851.         if i is None:
  3852.             return ""
  3853.         i = map(self.type2num, i)
  3854.         return struct.pack("!"+"I"*len(i),*i)
  3855.     def m2i(self, pkt, m):
  3856.         lst = struct.unpack("!"+"I"*(len(m)/4),m)
  3857.         lst = map(self.num2type, lst)
  3858.         return lst
  3859.     def getfield(self, pkt, s):
  3860.         l = getattr(pkt, self.fld)
  3861.         l += pkt.get_field(self.fld).shift
  3862.         i = self.m2i(pkt, s[:l])
  3863.       
  3864.         return s[l:],i
  3865.  
  3866. class StrNullField(StrField):
  3867.     def addfield(self, pkt, s, val):
  3868.         return s+self.i2m(pkt, val)+"\x00"
  3869.     def getfield(self, pkt, s):
  3870.         l = s.find("\x00")
  3871.         if l < 0:
  3872.             #XXX \x00 not found
  3873.             return "",s
  3874.         return s[l+1:],self.m2i(pkt, s[:l])
  3875.     def randval(self):
  3876.         return RandTermString(RandNum(0,1200),"\x00")
  3877.  
  3878. class StrStopField(StrField):
  3879.     def __init__(self, name, default, stop, additionnal=0):
  3880.         Field.__init__(self, name, default)
  3881.         self.stop=stop
  3882.         self.additionnal=additionnal
  3883.     def getfield(self, pkt, s):
  3884.         l = s.find(self.stop)
  3885.         if l < 0:
  3886.             return "",s
  3887. #            raise Exception,"StrStopField: stop value [%s] not found" %stop
  3888.         l += len(self.stop)+self.additionnal
  3889.         return s[l:],s[:l]
  3890.     def randval(self):
  3891.         return RandTermString(RandNum(0,1200),self.stop)
  3892.  
  3893. class LenField(Field):
  3894.     def i2m(self, pkt, x):
  3895.         if x is None:
  3896.             x = len(pkt.payload)
  3897.         return x
  3898.  
  3899. class BCDFloatField(Field):
  3900.     def i2m(self, pkt, x):
  3901.         return int(256*x)
  3902.     def m2i(self, pkt, x):
  3903.         return x/256.0
  3904.  
  3905. class BitField(Field):
  3906.     def __init__(self, name, default, size):
  3907.         Field.__init__(self, name, default)
  3908.         self.size = size
  3909.     def addfield(self, pkt, s, val):
  3910.         if val is None:
  3911.             val = 0
  3912.         if type(s) is tuple:
  3913.             s,bitsdone,v = s
  3914.         else:
  3915.             bitsdone = 0
  3916.             v = 0
  3917.         v <<= self.size
  3918.         v |= val & ((1L<<self.size) - 1)
  3919.         bitsdone += self.size
  3920.         while bitsdone >= 8:
  3921.             bitsdone -= 8
  3922.             s = s+struct.pack("!B", v >> bitsdone)
  3923.             v &= (1L<<bitsdone)-1
  3924.         if bitsdone:
  3925.             return s,bitsdone,v
  3926.         else:
  3927.             return s
  3928.     def getfield(self, pkt, s):
  3929.         if type(s) is tuple:
  3930.             s,bn = s
  3931.         else:
  3932.             bn = 0
  3933.         # we don't want to process all the string
  3934.         nb_bytes = (self.size+bn-1)/8 + 1
  3935.         w = s[:nb_bytes]
  3936.  
  3937.         # split the substring byte by byte
  3938.         bytes = struct.unpack('!%dB' % nb_bytes , w)
  3939.  
  3940.         b = 0L
  3941.         for c in range(nb_bytes):
  3942.             b |= long(bytes[c]) << (nb_bytes-c-1)*8
  3943.  
  3944.         # get rid of high order bits
  3945.         b &= (1L << (nb_bytes*8-bn)) - 1
  3946.  
  3947.         # remove low order bits
  3948.         b = b >> (nb_bytes*8 - self.size - bn)
  3949.  
  3950.         bn += self.size
  3951.         s = s[bn/8:]
  3952.         bn = bn%8
  3953.         if bn:
  3954.             return (s,bn),b
  3955.         else:
  3956.             return s,b
  3957.     def randval(self):
  3958.         return RandNum(0,2**self.size-1)
  3959.  
  3960. class XBitField(BitField):
  3961.     def i2repr(self, pkt, x):
  3962.         return hex(self.i2h(pkt,x))
  3963.  
  3964.  
  3965. class EnumField(Field):
  3966.     def __init__(self, name, default, enum, fmt = "H"):
  3967.         i2s = self.i2s = {}
  3968.         s2i = self.s2i = {}
  3969.         Field.__init__(self, name, default, fmt)
  3970.         if type(enum) is list:
  3971.             keys = xrange(len(enum))
  3972.         else:
  3973.             keys = enum.keys()
  3974.         if filter(lambda x: type(x) is str, keys):
  3975.             i2s,s2i = s2i,i2s
  3976.         for k in keys:
  3977.             i2s[k] = enum[k]
  3978.             s2i[enum[k]] = k
  3979.     def any2i_one(self, pkt, x):
  3980.         if type(x) is str:
  3981.             x = self.s2i[x]
  3982.         return x
  3983.     def i2repr_one(self, pkt, x):
  3984.         return self.i2s.get(x, repr(x))
  3985.     
  3986.     def any2i(self, pkt, x):
  3987.         if type(x) is list:
  3988.             return map(lambda z,pkt=pkt:self.any2i_one(pkt,z), x)
  3989.         else:
  3990.             return self.any2i_one(pkt,x)        
  3991.     def i2repr(self, pkt, x):
  3992.         if type(x) is list:
  3993.             return map(lambda z,pkt=pkt:self.i2repr_one(pkt,z), x)
  3994.         else:
  3995.             return self.i2repr_one(pkt,x)
  3996.  
  3997. class CharEnumField(EnumField):
  3998.     def __init__(self, name, default, enum, fmt = "1s"):
  3999.         EnumField.__init__(self, name, default, enum, fmt)
  4000.         k = self.i2s.keys()
  4001.         if k and len(k[0]) != 1:
  4002.             self.i2s,self.s2i = self.s2i,self.i2s
  4003.     def any2i_one(self, pkt, x):
  4004.         if len(x) != 1:
  4005.             x = self.s2i[x]
  4006.         return x
  4007.  
  4008. class BitEnumField(BitField,EnumField):
  4009.     def __init__(self, name, default, size, enum):
  4010.         EnumField.__init__(self, name, default, enum)
  4011.         self.size = size
  4012.     def any2i(self, pkt, x):
  4013.         return EnumField.any2i(self, pkt, x)
  4014.     def i2repr(self, pkt, x):
  4015.         return EnumField.i2repr(self, pkt, x)
  4016.  
  4017. class ShortEnumField(EnumField):
  4018.     def __init__(self, name, default, enum):
  4019.         EnumField.__init__(self, name, default, enum, "H")
  4020.  
  4021. class LEShortEnumField(EnumField):
  4022.     def __init__(self, name, default, enum):
  4023.         EnumField.__init__(self, name, default, enum, "@H")
  4024.  
  4025. class ByteEnumField(EnumField):
  4026.     def __init__(self, name, default, enum):
  4027.         EnumField.__init__(self, name, default, enum, "B")
  4028.  
  4029. class IntEnumField(EnumField):
  4030.     def __init__(self, name, default, enum):
  4031.         EnumField.__init__(self, name, default, enum, "I")
  4032.  
  4033. class LEIntEnumField(EnumField):
  4034.     def __init__(self, name, default, enum):
  4035.         EnumField.__init__(self, name, default, enum, "@I")
  4036.  
  4037. class XShortEnumField(ShortEnumField):
  4038.     def i2repr_one(self, pkt, x):
  4039.         return self.i2s.get(x, hex(x))            
  4040.  
  4041. # Little endian long field
  4042. class LELongField(Field):
  4043.     def __init__(self, name, default):
  4044.         Field.__init__(self, name, default, "@Q")
  4045.  
  4046. # Little endian fixed length field
  4047. class LEFieldLenField(Field):
  4048.     def __init__(self, name, default, fld, fmt = "@H", shift=0):
  4049.         Field.__init__(self, name, default, fmt)
  4050.         self.fld = fld
  4051.         self.shift = shift
  4052.     def i2m(self, pkt, x):
  4053.         if x is None:
  4054.             x = len(getattr(pkt, self.fld))-self.shift
  4055.         return x
  4056.     def i2h(self, pkt, x):
  4057.         if x is None:
  4058.             x = len(getattr(pkt, self.fld))+self.shift
  4059.         return x
  4060.  
  4061.  
  4062. class FlagsField(BitField):
  4063.     def __init__(self, name, default, size, names):
  4064.         BitField.__init__(self, name, default, size)
  4065.         self.multi = type(names) is list
  4066.         if self.multi:
  4067.             self.names = map(lambda x:[x], names)
  4068.         else:
  4069.             self.names = names
  4070.     def any2i(self, pkt, x):
  4071.         if type(x) is str:
  4072.             if self.multi:
  4073.                 x = map(lambda y:[y], x.split("+"))
  4074.             y = 0
  4075.             for i in x:
  4076.                 y |= 1 << self.names.index(i)
  4077.             x = y
  4078.         return x
  4079.     def i2repr(self, pkt, x):
  4080.         if self.multi:
  4081.             r = []
  4082.         else:
  4083.             r = ""
  4084.         i=0
  4085.         while x:
  4086.             if x & 1:
  4087.                 r += self.names[i]
  4088.             i += 1
  4089.             x >>= 1
  4090.         if self.multi:
  4091.             r = "+".join(r)
  4092.         return r
  4093.  
  4094.             
  4095.  
  4096.  
  4097.  
  4098. class IPoptionsField(StrField):
  4099.     def i2m(self, pkt, x):
  4100.         return x+"\x00"*(3-((len(x)+3)%4))
  4101.     def getfield(self, pkt, s):
  4102.         opsz = (pkt.ihl-5)*4
  4103.         if opsz < 0:
  4104.             warning("bad ihl (%i). Assuming ihl=5"%pkt.ihl)
  4105.             opsz = 0
  4106.         return s[opsz:],s[:opsz]
  4107.     def randval(self):
  4108.         return RandBin(RandNum(0,39))
  4109.  
  4110.  
  4111. TCPOptions = (
  4112.               { 2 : ("MSS","!H"),
  4113.                 3 : ("WScale","!B"),
  4114.                 4 : ["SAckOK",None],
  4115.                 5 : ["SAck","!II"],
  4116.                 8 : ["Timestamp","!II"],
  4117.                 14 : ["AltChkSum","!BH"],
  4118.                 15 : ["AltChkSumOpt",None]
  4119.                 },
  4120.               { "MSS":2,
  4121.                 "WScale":3,
  4122.                 "SAckOK":4,
  4123.                 "SAck":5,
  4124.                 "Timestamp":8,
  4125.                 "AltChkSum":14,
  4126.                 "AltChkSumOpt":15,
  4127.                 } )
  4128.  
  4129. class TCPOptionsField(StrField):
  4130.     islist=1
  4131.     def getfield(self, pkt, s):
  4132.         opsz = (pkt.dataofs-5)*4
  4133.         if opsz < 0:
  4134.             warning("bad dataofs (%i). Assuming dataofs=5"%pkt.dataofs)
  4135.             opsz = 0
  4136.         return s[opsz:],self.m2i(pkt,s[:opsz])
  4137.     def m2i(self, pkt, x):
  4138.         opt = []
  4139.         while x:
  4140.             onum = ord(x[0])
  4141.             if onum == 0:
  4142.                 break
  4143.             if onum == 1:
  4144.                 opt.append(("NOP",None))
  4145.                 x=x[1:]
  4146.                 continue
  4147.             olen = ord(x[1])
  4148.             oval = x[2:olen]
  4149.             if TCPOptions[0].has_key(onum):
  4150.                 oname, ofmt = TCPOptions[0][onum]
  4151.                 if ofmt:
  4152.                     oval = struct.unpack(ofmt, oval)
  4153.                     if len(oval) == 1:
  4154.                         oval = oval[0]
  4155.                 opt.append((oname, oval))
  4156.             else:
  4157.                 opt.append((onum, oval))
  4158.             x = x[olen:]
  4159.         return opt
  4160.     
  4161.     def i2m(self, pkt, x):
  4162.         opt = ""
  4163.         for oname,oval in x:
  4164.             if type(oname) is str:
  4165.                 if oname == "NOP":
  4166.                     opt += "\x01"
  4167.                     continue
  4168.                 elif TCPOptions[1].has_key(oname):
  4169.                     onum = TCPOptions[1][oname]
  4170.                     ofmt = TCPOptions[0][onum][1]
  4171.                     if ofmt is not None:
  4172.                         if type(oval) is not tuple:
  4173.                             oval = (oval,)
  4174.                         oval = struct.pack(ofmt, *oval)
  4175.                 else:
  4176.                     warning("option [%s] unknown. Skipped."%oname)
  4177.                     continue
  4178.             else:
  4179.                 onum = oname
  4180.                 if type(oval) is not str:
  4181.                     warning("option [%i] is not string."%onum)
  4182.                     continue
  4183.             opt += chr(onum)+chr(2+len(oval))+oval
  4184.         return opt+"\x00"*(3-((len(opt)+3)%4))
  4185.     def randval(self):
  4186.         return [] # XXX
  4187.     
  4188.  
  4189. class DNSStrField(StrField):
  4190.     def i2m(self, pkt, x):
  4191.         x = x.split(".")
  4192.         x = map(lambda y: chr(len(y))+y, x)
  4193.         x = "".join(x)
  4194.         if x[-1] != "\x00":
  4195.             x += "\x00"
  4196.         return x
  4197.     def getfield(self, pkt, s):
  4198.         n = ""
  4199.         while 1:
  4200.             l = ord(s[0])
  4201.             s = s[1:]
  4202.             if not l:
  4203.                 break
  4204.             if l & 0xc0:
  4205.                 raise Exception("DNS message can't be compressed at this point!")
  4206.             else:
  4207.                 n += s[:l]+"."
  4208.                 s = s[l:]
  4209.         return s, n
  4210.  
  4211.  
  4212. class DNSRRCountField(ShortField):
  4213.     def __init__(self, name, default, rr):
  4214.         ShortField.__init__(self, name, default)
  4215.         self.rr = rr
  4216.     def i2m(self, pkt, x):
  4217.         if x is None:
  4218.             x = getattr(pkt,self.rr)
  4219.             i = 0
  4220.             while isinstance(x, DNSRR) or isinstance(x, DNSQR):
  4221.                 x = x.payload
  4222.                 i += 1
  4223.             x = i
  4224.         return x
  4225.     def i2h(self, pkt, x):
  4226.         return self.i2m(pkt, x)
  4227.  
  4228.  
  4229.     
  4230.  
  4231. def DNSgetstr(s,p):
  4232.     name = ""
  4233.     q = 0
  4234.     jpath = [p]
  4235.     while 1:
  4236.         if p >= len(s):
  4237.             warning("DNS RR prematured end (ofs=%i, len=%i)"%(p,len(s)))
  4238.             break
  4239.         l = ord(s[p])
  4240.         p += 1
  4241.         if l & 0xc0:
  4242.             if not q:
  4243.                 q = p+1
  4244.             if p >= len(s):
  4245.                 warning("DNS incomplete jump token at (ofs=%i)" % p)
  4246.                 break
  4247.             p = ((l & 0x3f) << 8) + ord(s[p]) - 12
  4248.             if p in jpath:
  4249.                 warning("DNS decompression loop detected")
  4250.                 break
  4251.             jpath.append(p)
  4252.             continue
  4253.         elif l > 0:
  4254.             name += s[p:p+l]+"."
  4255.             p += l
  4256.             continue
  4257.         break
  4258.     if q:
  4259.         p = q
  4260.     return name,p
  4261.         
  4262.  
  4263. class DNSRRField(StrField):
  4264.     def __init__(self, name, countfld, passon=1):
  4265.         StrField.__init__(self, name, None)
  4266.         self.countfld = countfld
  4267.         self.passon = passon
  4268.     def i2m(self, pkt, x):
  4269.         if x is None:
  4270.             return ""
  4271.         return str(x)
  4272.     def decodeRR(self, name, s, p):
  4273.         ret = s[p:p+10]
  4274.         type,cls,ttl,rdlen = struct.unpack("!HHIH", ret)
  4275.         p += 10
  4276.         rr = DNSRR("\x00"+ret+s[p:p+rdlen])
  4277.         if rr.type in [2, 3, 4, 5]:
  4278.             rr.rdata = DNSgetstr(s,p)[0]
  4279.         del(rr.rdlen)
  4280.         
  4281.         p += rdlen
  4282.         
  4283.         rr.rrname = name
  4284.         return rr,p
  4285.     def getfield(self, pkt, s):
  4286.         if type(s) is tuple :
  4287.             s,p = s
  4288.         else:
  4289.             p = 0
  4290.         ret = None
  4291.         c = getattr(pkt, self.countfld)
  4292.         if c > len(s):
  4293.             warning("wrong value: DNS.%s=%i" % (self.countfld,c))
  4294.             return s,""
  4295.         while c:
  4296.             c -= 1
  4297.             name,p = DNSgetstr(s,p)
  4298.             rr,p = self.decodeRR(name, s, p)
  4299.             if ret is None:
  4300.                 ret = rr
  4301.             else:
  4302.                 ret.add_payload(rr)
  4303.         if self.passon:
  4304.             return (s,p),ret
  4305.         else:
  4306.             return s[p:],ret
  4307.             
  4308.             
  4309. class DNSQRField(DNSRRField):
  4310.     def decodeRR(self, name, s, p):
  4311.         ret = s[p:p+4]
  4312.         p += 4
  4313.         rr = DNSQR("\x00"+ret)
  4314.         rr.qname = name
  4315.         return rr,p
  4316.         
  4317.         
  4318.  
  4319. class RDataField(StrLenField):
  4320.     def m2i(self, pkt, s):
  4321.         family = None
  4322.         if pkt.type == 1:
  4323.         family = socket.AF_INET
  4324.     elif pkt.type == 28:
  4325.         family = socket.AF_INET6
  4326.     elif pkt.type == 12:
  4327.             s = DNSgetstr(s, 0)[0]
  4328.     if family is not None:    
  4329.         s = inet_ntop(family, s)
  4330.         return s
  4331.     def i2m(self, pkt, s):
  4332.         if pkt.type == 1:
  4333.             if s:
  4334.                 s = inet_aton(s)
  4335.         elif pkt.type == 28:        
  4336.             if s:
  4337.                 s = inet_pton(socket.AF_INET6, s)
  4338.         elif pkt.type in [2,3,4,5]:
  4339.             s = "".join(map(lambda x: chr(len(x))+x, s.split(".")))
  4340.             if ord(s[-1]):
  4341.                 s += "\x00"
  4342.         return s
  4343.  
  4344. class RDLenField(Field):
  4345.     def __init__(self, name):
  4346.         Field.__init__(self, name, None, "H")
  4347.     def i2m(self, pkt, x):
  4348.         if x is None:
  4349.             rdataf = pkt.fieldtype["rdata"]
  4350.             x = len(rdataf.i2m(pkt, pkt.rdata))
  4351.         return x
  4352.     def i2h(self, pkt, x):
  4353.         if x is None:
  4354.             rdataf = pkt.fieldtype["rdata"]
  4355.             x = len(rdataf.i2m(pkt, pkt.rdata))
  4356.         return x
  4357.     
  4358. # seconds between 01-01-1900 and 01-01-1970
  4359. ntp_basetime = 2208988800
  4360.  
  4361. class TimeStampField(BitField):
  4362.     def __init__(self, name, default, size):
  4363.         BitField.__init__(self, name, default, size)
  4364.         self.size  = size
  4365.     def getfield(self, pkt, s):
  4366.         s,timestamp = BitField.getfield(self, pkt, s)
  4367.  
  4368.         if timestamp:
  4369.             # timestamp is a 64 bits field :
  4370.             #  + first 32 bits : number of seconds since 1900
  4371.             #  + last 32 bits  : fraction part
  4372.             timestamp >>= 32
  4373.             timestamp -= ntp_basetime
  4374.             
  4375.             from time import gmtime, strftime
  4376.             b = strftime("%a, %d %b %Y %H:%M:%S +0000", gmtime(timestamp))
  4377.         else:
  4378.             b = 'None'
  4379.         
  4380.         return s, b
  4381.     def addfield(self, pkt, s, val):
  4382.         t = -1
  4383.         if type(val) is str:
  4384.             from time import strptime, mktime
  4385.             t = int(mktime(strptime(val))) + ntp_basetime + 3600
  4386.         else:
  4387.             if val == -1:
  4388.                 from time import time
  4389.                 t = int(time()) + ntp_basetime
  4390.             else:
  4391.                 t = val
  4392.         t <<= 32
  4393.         return BitField.addfield(self,pkt,s, t)
  4394.  
  4395. class FloatField(BitField):
  4396.     def getfield(self, pkt, s):
  4397.         s,b = BitField.getfield(self, pkt, s)
  4398.         
  4399.         # fraction point between bits 15 and 16.
  4400.         sec = b >> 16
  4401.         frac = b & (1L << (32+1)) - 1
  4402.         frac /= 65536.0
  4403.         b = sec+frac
  4404.         return s,b    
  4405.  
  4406. ###########################
  4407. ## Packet abstract class ##
  4408. ###########################
  4409.  
  4410.  
  4411. class Packet(Gen):
  4412.     name="abstract packet"
  4413.  
  4414.     fields_desc = []
  4415.  
  4416.     aliastypes = []
  4417.     overload_fields = {}
  4418.  
  4419.     underlayer = None
  4420.  
  4421.     payload_guess = []
  4422.     initialized = 0
  4423.     show_indent=1
  4424.  
  4425.     def __init__(self, _pkt="", _internal=0, _underlayer=None, **fields):
  4426.         self.time  = time.time()
  4427.         self.aliastypes = [ self.__class__ ] + self.aliastypes
  4428.         self.default_fields = {}
  4429.         self.overloaded_fields = {}
  4430.         self.fields={}
  4431.         self.fieldtype={}
  4432.         self.__dict__["payload"] = NoPayload()
  4433.         for f in self.fields_desc:
  4434.             self.default_fields[f] = f.default
  4435.             self.fieldtype[f] = f
  4436.         self.underlayer = _underlayer
  4437.         self.initialized = 1
  4438.         if _pkt:
  4439.             self.dissect(_pkt)
  4440.             if not _internal:
  4441.                 self.dissection_done(self)
  4442.         for f in fields.keys():
  4443.             self.fields[f] = self.fieldtype[f].any2i(self,fields[f])
  4444.             
  4445.     def dissection_done(self,pkt):
  4446.         """DEV: will be called after a dissection is completed"""
  4447.         self.post_dissection(pkt)
  4448.         self.payload.dissection_done(pkt)
  4449.         
  4450.     def post_dissection(self, pkt):
  4451.         """DEV: is called right after the dissection of the current layer"""
  4452.         pass
  4453.  
  4454.     def get_field(self, fld):
  4455.         """DEV: returns the field instance from the name of the field"""
  4456.         return self.fields_desc[self.fields_desc.index(fld)]
  4457.         
  4458.     def add_payload(self, payload):
  4459.         if payload is None:
  4460.             return
  4461.         elif not isinstance(self.payload, NoPayload):
  4462.             self.payload.add_payload(payload)
  4463.         else:
  4464.             if isinstance(payload, Packet):
  4465.                 self.__dict__["payload"] = payload
  4466.                 payload.add_underlayer(self)
  4467.                 for t in self.aliastypes:
  4468.                     if payload.overload_fields.has_key(t):
  4469.                         self.overloaded_fields = payload.overload_fields[t]
  4470.                         break
  4471.             elif type(payload) is str:
  4472.                 self.__dict__["payload"] = Raw(load=payload)
  4473.             else:
  4474.                 raise TypeError("payload must be either 'Packet' or 'str', not [%s]" % repr(payload))
  4475.     def remove_payload(self):
  4476.         self.payload.remove_underlayer(self)
  4477.         self.__dict__["payload"] = NoPayload()
  4478.         self.overloaded_fields = {}
  4479.     def add_underlayer(self, underlayer):
  4480.         self.underlayer = underlayer
  4481.     def remove_underlayer(self,other):
  4482.         self.underlayer = None
  4483.     def copy(self):
  4484.         """Returns a deep copy of the instance."""
  4485.         clone = self.__class__()
  4486.         clone.fields = self.fields.copy()
  4487.         for k in clone.fields:
  4488.             clone.fields[k]=self.fieldtype[k].do_copy(clone.fields[k])
  4489.         clone.default_fields = self.default_fields.copy()
  4490.         clone.overloaded_fields = self.overloaded_fields.copy()
  4491.         clone.overload_fields = self.overload_fields.copy()
  4492.         clone.underlayer=self.underlayer
  4493.         clone.__dict__["payload"] = self.payload.copy()
  4494.         clone.payload.add_underlayer(clone)
  4495.         return clone
  4496.     def __getattr__(self, attr):
  4497.         if self.initialized:
  4498.             fld = self.fieldtype.get(attr)
  4499.             if fld is None:
  4500.                 i2h = lambda x,y: y
  4501.             else:
  4502.                 i2h = fld.i2h
  4503.             for f in ["fields", "overloaded_fields", "default_fields"]:
  4504.                 fields = self.__dict__[f]
  4505.                 if fields.has_key(attr):
  4506.                     return i2h(self, fields[attr] )
  4507.             return getattr(self.payload, attr)
  4508.         raise AttributeError(attr)
  4509.  
  4510.     def __setattr__(self, attr, val):
  4511.         if self.initialized:
  4512.             if self.default_fields.has_key(attr):
  4513.                 fld = self.fieldtype.get(attr)
  4514.                 if fld is None:
  4515.                     any2i = lambda x,y: y
  4516.                 else:
  4517.                     any2i = fld.any2i
  4518.                 self.fields[attr] = any2i(self, val)
  4519.             elif attr == "payload":
  4520.                 self.remove_payload()
  4521.                 self.add_payload(val)
  4522.             else:
  4523.                 self.__dict__[attr] = val
  4524.         else:
  4525.             self.__dict__[attr] = val
  4526.     def __delattr__(self, attr):
  4527.         if self.initialized:
  4528.             if self.fields.has_key(attr):
  4529.                 del(self.fields[attr])
  4530.                 return
  4531.             elif self.default_fields.has_key(attr):
  4532.                 return
  4533.             elif attr == "payload":
  4534.                 self.remove_payload()
  4535.                 return
  4536.         if self.__dict__.has_key(attr):
  4537.             del(self.__dict__[attr])
  4538.         else:
  4539.             raise AttributeError(attr)
  4540.             
  4541.     def __repr__(self):
  4542.         s = ""
  4543.         ct = conf.color_theme
  4544.         for f in self.fields_desc:
  4545.             if f in self.fields:
  4546.                 val = f.i2repr(self, self.fields[f])
  4547.             elif f in self.overloaded_fields:
  4548.                 val =  f.i2repr(self, self.overloaded_fields[f])
  4549.             else:
  4550.                 continue
  4551.             if isinstance(f, Emph):
  4552.                 ncol = ct.emph_field_name
  4553.                 vcol = ct.emph_field_value
  4554.             else:
  4555.                 ncol = ct.field_name
  4556.                 vcol = ct.field_value
  4557.  
  4558.                 
  4559.             s += " %s%s%s" % (ncol(f.name),
  4560.                               ct.punct("="),
  4561.                               vcol(val))
  4562.         return "%s%s %s %s%s%s"% (ct.punct("<"),
  4563.                                   ct.layer_name(self.__class__.__name__),
  4564.                                   s,
  4565.                                   ct.punct("|"),
  4566.                                   repr(self.payload),
  4567.                                   ct.punct(">"))
  4568.     def __str__(self):
  4569.         return self.__iter__().next().build()
  4570.     def __div__(self, other):
  4571.         if isinstance(other, Packet):
  4572.             cloneA = self.copy()
  4573.             cloneB = other.copy()
  4574.             cloneA.add_payload(cloneB)
  4575.             return cloneA
  4576.         elif type(other) is str:
  4577.             return self/Raw(load=other)
  4578.         else:
  4579.             return other.__rdiv__(self)
  4580.     def __rdiv__(self, other):
  4581.         if type(other) is str:
  4582.             return Raw(load=other)/self
  4583.         else:
  4584.             raise TypeError
  4585.     def __len__(self):
  4586.         return len(self.__str__())
  4587.     def do_build(self):
  4588.         p=""
  4589.         for f in self.fields_desc:
  4590.             p = f.addfield(self, p, self.__getattr__(f))
  4591.         pkt = p+self.payload.build(internal=1)
  4592.         return pkt
  4593.     
  4594.     def post_build(self, pkt):
  4595.         """DEV: called right after the current layer is build."""
  4596.         return pkt
  4597.  
  4598.     def build(self,internal=0):
  4599.         p = self.post_build(self.do_build())
  4600.         if not internal:
  4601.             pkt = self
  4602.             while pkt.haslayer(Padding):
  4603.                 pkt = pkt.getlayer(Padding)
  4604.                 p += pkt.load
  4605.                 pkt = pkt.payload
  4606.         return p
  4607.  
  4608.     def do_build_ps(self):
  4609.         p=""
  4610.         pl = []
  4611.         q=""
  4612.         for f in self.fields_desc:
  4613.             p = f.addfield(self, p, self.__getattr__(f) )
  4614.             if type(p) is str:
  4615.                 r = p[len(q):]
  4616.                 q = p
  4617.             else:
  4618.                 r = ""
  4619.             pl.append( (f, f.i2repr(self,self.__getattr__(f)), r) )
  4620.             
  4621.         pkt,lst = self.payload.build_ps(internal=1)
  4622.         p += pkt
  4623.         lst.append( (self, pl) )
  4624.         
  4625.         return p,lst
  4626.     
  4627.     def build_ps(self,internal=0):
  4628.         p,lst = self.do_build_ps()
  4629. #        if not internal:
  4630. #            pkt = self
  4631. #            while pkt.haslayer(Padding):
  4632. #                pkt = pkt.getlayer(Padding)
  4633. #                lst.append( (pkt, [ ("loakjkjd", pkt.load, pkt.load) ] ) )
  4634. #                p += pkt.load
  4635. #                pkt = pkt.payload
  4636.         return p,lst
  4637.  
  4638.  
  4639.     def psdump(self, filename=None, **kargs):
  4640.         """Creates an EPS file describing a packet. If filename is not provided a temporary file is created and gs is called."""
  4641.         canvas = self.canvas_dump(**kargs)
  4642.         if filename is None:
  4643.             fname = "/tmp/scapy.%i"%os.getpid()
  4644.             canvas.writeEPSfile(fname)
  4645.             os.system("%s '%s.eps' &" % (conf.prog.psreader,fname))
  4646.         else:
  4647.             canvas.writeEPSfile(filename)
  4648.  
  4649.     def pdfdump(self, filename=None, **kargs):
  4650.         """Creates a PDF file describing a packet. If filename is not provided a temporary file is created and xpdf is called."""
  4651.         canvas = self.canvas_dump(**kargs)
  4652.         if filename is None:
  4653.             fname = "/tmp/scapy.%i"%os.getpid()
  4654.             canvas.writePDFfile(fname)
  4655.             os.system("%s '%s.pdf' &" % (conf.prog.pdfreader,fname))
  4656.         else:
  4657.             canvas.writePDFfile(filename)
  4658.  
  4659.         
  4660.     def canvas_dump(self, layer_shift=0, rebuild=1):
  4661.         canvas = pyx.canvas.canvas()
  4662.         if rebuild:
  4663.             p,t = self.__class__(str(self)).build_ps()
  4664.         else:
  4665.             p,t = self.build_ps()
  4666.         YTXT=len(t)
  4667.         for n,l in t:
  4668.             YTXT += len(l)
  4669.         YTXT = float(YTXT)
  4670.         YDUMP=YTXT
  4671.  
  4672.         XSTART = 1
  4673.         XDSTART = 10
  4674.         y = 0.0
  4675.         yd = 0.0
  4676.         xd = 0 
  4677.         XMUL= 0.55
  4678.         YMUL = 0.4
  4679.     
  4680.         backcolor=colgen(0.6, 0.8, 1.0, trans=pyx.color.rgb)
  4681.         forecolor=colgen(0.2, 0.5, 0.8, trans=pyx.color.rgb)
  4682. #        backcolor=makecol(0.376, 0.729, 0.525, 1.0)
  4683.         
  4684.         
  4685.         def hexstr(x):
  4686.             s = []
  4687.             for c in x:
  4688.                 s.append("%02x" % ord(c))
  4689.             return " ".join(s)
  4690.  
  4691.                 
  4692.         def make_dump_txt(x,y,txt):
  4693.             return pyx.text.text(XDSTART+x*XMUL, (YDUMP-y)*YMUL, r"\tt{%s}"%hexstr(txt), [pyx.text.size.Large])
  4694.  
  4695.         def make_box(o):
  4696.             return pyx.box.rect(o.left(), o.bottom(), o.width(), o.height(), relcenter=(0.5,0.5))
  4697.  
  4698.         def make_frame(lst):
  4699.             if len(lst) == 1:
  4700.                 b = lst[0].bbox()
  4701.                 b.enlarge(pyx.unit.u_pt)
  4702.                 return b.path()
  4703.             else:
  4704.                 fb = lst[0].bbox()
  4705.                 fb.enlarge(pyx.unit.u_pt)
  4706.                 lb = lst[-1].bbox()
  4707.                 lb.enlarge(pyx.unit.u_pt)
  4708.                 if len(lst) == 2 and fb.left() > lb.right():
  4709.                     return pyx.path.path(pyx.path.moveto(fb.right(), fb.top()),
  4710.                                          pyx.path.lineto(fb.left(), fb.top()),
  4711.                                          pyx.path.lineto(fb.left(), fb.bottom()),
  4712.                                          pyx.path.lineto(fb.right(), fb.bottom()),
  4713.                                          pyx.path.moveto(lb.left(), lb.top()),
  4714.                                          pyx.path.lineto(lb.right(), lb.top()),
  4715.                                          pyx.path.lineto(lb.right(), lb.bottom()),
  4716.                                          pyx.path.lineto(lb.left(), lb.bottom()))
  4717.                 else:
  4718.                     # XXX
  4719.                     gb = lst[1].bbox()
  4720.                     if gb != lb:
  4721.                         gb.enlarge(pyx.unit.u_pt)
  4722.                     kb = lst[-2].bbox()
  4723.                     if kb != gb and kb != lb:
  4724.                         kb.enlarge(pyx.unit.u_pt)
  4725.                     return pyx.path.path(pyx.path.moveto(fb.left(), fb.top()),
  4726.                                          pyx.path.lineto(fb.right(), fb.top()),
  4727.                                          pyx.path.lineto(fb.right(), kb.bottom()),
  4728.                                          pyx.path.lineto(lb.right(), kb.bottom()),
  4729.                                          pyx.path.lineto(lb.right(), lb.bottom()),
  4730.                                          pyx.path.lineto(lb.left(), lb.bottom()),
  4731.                                          pyx.path.lineto(lb.left(), gb.top()),
  4732.                                          pyx.path.lineto(fb.left(), gb.top()),
  4733.                                          pyx.path.closepath(),)
  4734.                                          
  4735.  
  4736.         def make_dump(s, shift=0, y=0, col=None, bkcol=None, larg=16):
  4737.             c = pyx.canvas.canvas()
  4738.             tlist = []
  4739.             while s:
  4740.                 dmp,s = s[:larg-shift],s[larg-shift:]
  4741.                 txt = make_dump_txt(shift, y, dmp)
  4742.                 tlist.append(txt)
  4743.                 shift += len(dmp)
  4744.                 if shift >= 16:
  4745.                     shift = 0
  4746.                     y += 1
  4747.             if col is None:
  4748.                 col = pyx.color.rgb.red
  4749.             if bkcol is None:
  4750.                 col = pyx.color.rgb.white
  4751.             c.stroke(make_frame(tlist),[col,pyx.deco.filled([bkcol]),pyx.style.linewidth.Thick])
  4752.             for txt in tlist:
  4753.                 c.insert(txt)
  4754.             return c, tlist[-1].bbox(), shift, y
  4755.                             
  4756.  
  4757.         last_shift,last_y=0,0.0
  4758.         while t:
  4759.             bkcol = backcolor.next()
  4760.             proto,fields = t.pop()
  4761.             y += 0.5
  4762.             pt = pyx.text.text(XSTART, (YTXT-y)*YMUL, r"\font\cmssfont=cmss10\cmssfont{%s}" % proto.name, [ pyx.text.size.Large])
  4763.             y += 1
  4764.             ptbb=pt.bbox()
  4765.             ptbb.enlarge(pyx.unit.u_pt*2)
  4766.             canvas.stroke(ptbb.path(),[pyx.color.rgb.black, pyx.deco.filled([bkcol])])
  4767.             canvas.insert(pt)
  4768.             for fname, fval, fdump in fields:
  4769.                 col = forecolor.next()
  4770.                 ft = pyx.text.text(XSTART, (YTXT-y)*YMUL, r"\font\cmssfont=cmss10\cmssfont{%s}" % tex_escape(fname.name))
  4771.                 if fval is not None:
  4772.                     if len(fval) > 18:
  4773.                         fval = fval[:18]+"[...]"
  4774.                 else:
  4775.                     fval=""
  4776.                 vt = pyx.text.text(XSTART+3, (YTXT-y)*YMUL, r"\font\cmssfont=cmss10\cmssfont{%s}" % tex_escape(fval))
  4777.                 y += 1.0
  4778.                 if fdump:
  4779.                     dt,target,last_shift,last_y = make_dump(fdump, last_shift, last_y, col, bkcol)
  4780.  
  4781.                     dtb = dt.bbox()
  4782.                     dtb=target
  4783.                     vtb = vt.bbox()
  4784.                     bxvt = make_box(vtb)
  4785.                     bxdt = make_box(dtb)
  4786.                     dtb.enlarge(pyx.unit.u_pt)
  4787.                     try:
  4788.                         if yd < 0:
  4789.                             cnx = pyx.connector.curve(bxvt,bxdt,absangle1=0, absangle2=-90)
  4790.                         else:
  4791.                             cnx = pyx.connector.curve(bxvt,bxdt,absangle1=0, absangle2=90)
  4792.                     except:
  4793.                         pass
  4794.                     else:
  4795.                         canvas.stroke(cnx,[pyx.style.linewidth.thin,pyx.deco.earrow.small,col])
  4796.                         
  4797.                     canvas.insert(dt)
  4798.                 
  4799.                 canvas.insert(ft)
  4800.                 canvas.insert(vt)
  4801.             last_y += layer_shift
  4802.     
  4803.         return canvas
  4804.  
  4805.  
  4806.  
  4807.     def extract_padding(self, s):
  4808.         """DEV: to be overloaded to extract current layer's padding. Return a couple of strings (actual layer, padding)"""
  4809.         return s,None
  4810.  
  4811.     def post_dissect(self, s):
  4812.         """DEV: is called right after the current layer has been dissected"""
  4813.         return s
  4814.  
  4815.     def do_dissect(self, s):
  4816.         flist = self.fields_desc[:]
  4817.         flist.reverse()
  4818.         while s and flist:
  4819.             f = flist.pop()
  4820.             s,fval = f.getfield(self, s)
  4821.             self.fields[f] = fval
  4822.  
  4823.         s = self.post_dissect(s)
  4824.             
  4825.         payl,pad = self.extract_padding(s)
  4826.         self.do_dissect_payload(payl)
  4827.         if pad and conf.padding:
  4828.             self.add_payload(Padding(pad))
  4829.     def do_dissect_payload(self, s):
  4830.         if s:
  4831.             cls = self.guess_payload_class(s)
  4832.             try:
  4833.                 p = cls(s, _internal=1, _underlayer=self)
  4834.             except:
  4835.                 if conf.debug_dissector:
  4836.                     if type(cls) is type and issubclass(cls,Packet):
  4837.                         log_runtime.error("%s dissector failed" % cls.name)
  4838.                     else:
  4839.                         log_runtime.error("%s.guess_payload_class() returned [%s]" % (self.__class__.__name__,repr(cls)))
  4840.                     if cls is not None:
  4841.                         raise
  4842.                 p = Raw(s, _internal=1, _underlayer=self)
  4843.             self.add_payload(p)
  4844.  
  4845.     def dissect(self, s):
  4846.         return self.do_dissect(s)
  4847.  
  4848.     def guess_payload_class(self, payload):
  4849.         """DEV: Guesses the next payload class from layer bonds. Can be overloaded to use a different mechanism."""
  4850.         for t in self.aliastypes:
  4851.             for fval, cls in t.payload_guess:
  4852.                 ok = 1
  4853.                 for k in fval.keys():
  4854.                     if fval[k] != getattr(self,k):
  4855.                         ok = 0
  4856.                         break
  4857.                 if ok:
  4858.                     return cls
  4859.         return self.default_payload_class(payload)
  4860.     
  4861.     def default_payload_class(self, payload):
  4862.         """DEV: Returns the default payload class if nothing has been found by the guess_payload_class() method."""
  4863.         return Raw
  4864.  
  4865.     def hide_defaults(self):
  4866.         """Removes fields' values that are the same as default values."""
  4867.         for k in self.fields.keys():
  4868.             if self.default_fields.has_key(k):
  4869.                 if self.default_fields[k] == self.fields[k]:
  4870.                     del(self.fields[k])
  4871.         self.payload.hide_defaults()
  4872.             
  4873.  
  4874.     def __iter__(self):
  4875.         def loop(todo, done, self=self):
  4876.             if todo:
  4877.                 eltname = todo.pop()
  4878.                 elt = self.__getattr__(eltname)
  4879.                 if not isinstance(elt, Gen):
  4880.                     if self.fieldtype[eltname].islist:
  4881.                         elt = SetGen([elt])
  4882.                     else:
  4883.                         elt = SetGen(elt)
  4884.                 for e in elt:
  4885.                     done[eltname]=e
  4886.                     for x in loop(todo[:], done):
  4887.                         yield x
  4888.             else:
  4889.                 if isinstance(self.payload,NoPayload):
  4890.                     payloads = [None]
  4891.                 else:
  4892.                     payloads = self.payload
  4893.                 for payl in payloads:
  4894.                     done2=done.copy()
  4895.                     for k in done2:
  4896.                         if isinstance(done2[k], VolatileValue):
  4897.                             done2[k] = done2[k]._fix()
  4898.                     pkt = self.__class__(**done2)
  4899.                     pkt.underlayer = self.underlayer
  4900.                     pkt.overload_fields = self.overload_fields.copy()
  4901.                     if payl is None:
  4902.                         yield pkt
  4903.                     else:
  4904.                         yield pkt/payl
  4905.         todo = map(lambda (x,y):x, filter(lambda (x,y):isinstance(y,VolatileValue), self.default_fields.items()))
  4906.         todo += self.fields.keys()
  4907.         return loop(map(lambda x:str(x), todo), {})
  4908.  
  4909.     def __gt__(self, other):
  4910.         """True if other is an answer from self (self ==> other)."""
  4911.         if isinstance(other, Packet):
  4912.             return other < self
  4913.         elif type(other) is str:
  4914.             return 1
  4915.         else:
  4916.             raise TypeError((self, other))
  4917.     def __lt__(self, other):
  4918.         """True if self is an answer from other (other ==> self)."""
  4919.         if isinstance(other, Packet):
  4920.             return self.answers(other)
  4921.         elif type(other) is str:
  4922.             return 1
  4923.         else:
  4924.             raise TypeError((self, other))
  4925.  
  4926.     def __eq__(self, other):
  4927.         if not isinstance(other, self.__class__):
  4928.             return False
  4929.         for f in self.fields_desc:
  4930.             if f not in other.fields_desc:
  4931.                 return False
  4932.             if getattr(self, f.name) != getattr(other, f.name):
  4933.                 return False
  4934.         return self.payload == other.payload
  4935.  
  4936.     def __ne__(self, other):
  4937.         return not self.__eq__(other)
  4938.  
  4939.     def hashret(self):
  4940.         """DEV: returns a string that has the same value for a request and its answer."""
  4941.         return self.payload.hashret()
  4942.     def answers(self, other):
  4943.         """DEV: true if self is an answer from other"""
  4944.         if other.__class__ == self.__class__:
  4945.             return self.payload.answers(other.payload)
  4946.         return 0
  4947.  
  4948.     def haslayer(self, cls):
  4949.         """true if self has a layer that is an instance of cls. Superseded by "cls in self" syntax."""
  4950.         if self.__class__ == cls or self.__class__.__name__ == cls:
  4951.             return 1
  4952.         for f in self.fields_desc:
  4953.             fvalue = self.__getattr__(f)
  4954.             if isinstance(fvalue, Packet):
  4955.                 ret = fvalue.haslayer(cls)
  4956.                 if ret:
  4957.                     return ret
  4958.         return self.payload.haslayer(cls)
  4959.     def getlayer(self, cls, nb=1, _track=None):
  4960.         """Return the nb^th layer that is an instance of cls."""
  4961.         if self.__class__ == cls or self.__class__.name == cls:
  4962.             if nb == 1:
  4963.                 return self
  4964.             else:
  4965.                 nb -=1
  4966.         for f in self.fields_desc:
  4967.             fvalue = self.__getattr__(f)
  4968.             if isinstance(fvalue, Packet):
  4969.                 track=[]
  4970.                 ret = fvalue.getlayer(cls, nb, _track=track)
  4971.                 if ret is not None:
  4972.                     return ret
  4973.                 nb = track[0]
  4974.         return self.payload.getlayer(cls,nb,_track=_track)
  4975.  
  4976.     def __getitem__(self, cls):
  4977.         if type(cls) is slice:
  4978.             if cls.stop:
  4979.                 ret = self.getlayer(cls.start, cls.stop)
  4980.             else:
  4981.                 ret = self.getlayer(cls.start)
  4982.             if ret is None and cls.step is not None:
  4983.                 ret = cls.step
  4984.             return ret
  4985.         else:
  4986.             return self.getlayer(cls)
  4987.         
  4988.     def __contains__(self, cls):
  4989.         """"cls in self" returns true if self has a layer which is an instance of cls."""
  4990.         return self.haslayer(cls)
  4991.         
  4992.     
  4993.  
  4994.     def display(self,*args,**kargs):  # Deprecated. Use show()
  4995.         """Deprecated. Use show() method."""
  4996.         self.show(*args,**kargs)
  4997.     def show(self, indent=3, lvl="", label_lvl=""):
  4998.         """Prints a hierarchical view of the packet. "indent" gives the size of indentation for each layer."""
  4999.         ct = conf.color_theme
  5000.         print "%s%s %s %s" % (label_lvl,
  5001.                               ct.punct("###["),
  5002.                               ct.layer_name(self.name),
  5003.                               ct.punct("]###"))
  5004.         for f in self.fields_desc:
  5005.             if isinstance(f, Emph):
  5006.                 ncol = ct.emph_field_name
  5007.                 vcol = ct.emph_field_value
  5008.             else:
  5009.                 ncol = ct.field_name
  5010.                 vcol = ct.field_value
  5011.             fvalue = self.__getattr__(f)
  5012.             if isinstance(fvalue, Packet):
  5013.                 print "%s  \\%-10s\\" % (label_lvl+lvl,
  5014.                                      ncol(f.name))
  5015.                 
  5016.                 self.__getattr__(f).show(indent=indent, label_lvl=label_lvl+lvl+"   |")
  5017.             else:
  5018.                 print "%s  %-10s%s %s" % (label_lvl+lvl,
  5019.                                           ncol(f.name),
  5020.                                           ct.punct("="),
  5021.                                           vcol(f.i2repr(self,fvalue)))
  5022.         self.payload.show(indent=indent, lvl=lvl+(" "*indent*self.show_indent), label_lvl=label_lvl)
  5023.     def show2(self):
  5024.         """Prints a hierarchical view of an assembled version of the packet, so that automatic fields are calculated (checksums, etc.)"""
  5025.         self.__class__(str(self)).show()
  5026.  
  5027.     def sprintf(self, fmt, relax=1):
  5028.         """sprintf(format, [relax=1]) -> str
  5029. where format is a string that can include directives. A directive begins and
  5030. ends by % and has the following format %[fmt[r],][cls[:nb].]field%.
  5031.  
  5032. fmt is a classic printf directive, "r" can be appended for raw substitution
  5033. (ex: IP.flags=0x18 instead of SA), nb is the number of the layer we want
  5034. (ex: for IP/IP packets, IP:2.src is the src of the upper IP layer).
  5035. Special case : "%.time%" is the creation time.
  5036. Ex : p.sprintf("%.time% %-15s,IP.src% -> %-15s,IP.dst% %IP.chksum% "
  5037.                "%03xr,IP.proto% %r,TCP.flags%")
  5038.  
  5039. Moreover, the format string can include conditionnal statements. A conditionnal
  5040. statement looks like : {layer:string} where layer is a layer name, and string
  5041. is the string to insert in place of the condition if it is true, i.e. if layer
  5042. is present. If layer is preceded by a "!", the result si inverted. Conditions
  5043. can be imbricated. A valid statement can be :
  5044.   p.sprintf("This is a{TCP: TCP}{UDP: UDP}{ICMP:n ICMP} packet")
  5045.   p.sprintf("{IP:%IP.dst% {ICMP:%ICMP.type%}{TCP:%TCP.dport%}}")
  5046.  
  5047. A side effect is that, to obtain "{" and "}" characters, you must use
  5048. "%(" and "%)".
  5049. """
  5050.  
  5051.         escape = { "%": "%",
  5052.                    "(": "{",
  5053.                    ")": "}" }
  5054.  
  5055.  
  5056.         # Evaluate conditions 
  5057.         while "{" in fmt:
  5058.             i = fmt.rindex("{")
  5059.             j = fmt[i+1:].index("}")
  5060.             cond = fmt[i+1:i+j+1]
  5061.             k = cond.find(":")
  5062.             if k < 0:
  5063.                 raise Exception("Bad condition in format string: [%s] (read sprintf doc!)"%cond)
  5064.             cond,format = cond[:k],cond[k+1:]
  5065.             res = False
  5066.             if cond[0] == "!":
  5067.                 res = True
  5068.                 cond = cond[1:]
  5069.             if self.haslayer(cond):
  5070.                 res = not res
  5071.             if not res:
  5072.                 format = ""
  5073.             fmt = fmt[:i]+format+fmt[i+j+2:]
  5074.  
  5075.         # Evaluate directives
  5076.         s = ""
  5077.         while "%" in fmt:
  5078.             i = fmt.index("%")
  5079.             s += fmt[:i]
  5080.             fmt = fmt[i+1:]
  5081.             if fmt[0] in escape:
  5082.                 s += escape[fmt[0]]
  5083.                 fmt = fmt[1:]
  5084.                 continue
  5085.             try:
  5086.                 i = fmt.index("%")
  5087.                 sfclsfld = fmt[:i]
  5088.                 fclsfld = sfclsfld.split(",")
  5089.                 if len(fclsfld) == 1:
  5090.                     f = "s"
  5091.                     clsfld = fclsfld[0]
  5092.                 elif len(fclsfld) == 2:
  5093.                     f,clsfld = fclsfld
  5094.                 else:
  5095.                     raise Exception
  5096.                 if "." in clsfld:
  5097.                     cls,fld = clsfld.split(".")
  5098.                 else:
  5099.                     cls = self.__class__.__name__
  5100.                     fld = clsfld
  5101.                 num = 1
  5102.                 if ":" in cls:
  5103.                     cls,num = cls.split(":")
  5104.                     num = int(num)
  5105.                 fmt = fmt[i+1:]
  5106.             except:
  5107.                 raise Exception("Bad format string [%%%s%s]" % (fmt[:25], fmt[25:] and "..."))
  5108.             else:
  5109.                 if fld == "time":
  5110.                     val = time.strftime("%H:%M:%S.%%06i", time.localtime(self.time)) % int((self.time-int(self.time))*1000000)
  5111.                 elif cls == self.__class__.__name__ and hasattr(self, fld):
  5112.                     if num > 1:
  5113.                         val = self.payload.sprintf("%%%s,%s:%s.%s%%" % (f,cls,num-1,fld), relax)
  5114.                         f = "s"
  5115.                     elif f[-1] == "r":  # Raw field value
  5116.                         val = getattr(self,fld)
  5117.                         f = f[:-1]
  5118.                         if not f:
  5119.                             f = "s"
  5120.                     else:
  5121.                         val = getattr(self,fld)
  5122.                         if fld in self.fieldtype:
  5123.                             val = self.fieldtype[fld].i2repr(self,val)
  5124.                 else:
  5125.                     val = self.payload.sprintf("%%%s%%" % sfclsfld, relax)
  5126.                     f = "s"
  5127.                 s += ("%"+f) % val
  5128.             
  5129.         s += fmt
  5130.         return s
  5131.  
  5132.     def mysummary(self):
  5133.         """DEV: can be overloaded to return a string that summarizes the layer.
  5134.            Only one mysummary() is used in a whole packet summary: the one of the upper layer,
  5135.            except if a mysummary() also returns (as a couple) a list of layers whose
  5136.            mysummary() must be called if they are present."""
  5137.         return ""
  5138.  
  5139.     def summary(self, intern=0):
  5140.         """Prints a one line summary of a packet."""
  5141.         found,s,needed = self.payload.summary(intern=1)
  5142.         if s:
  5143.             s = " / "+s
  5144.         ret = ""
  5145.         if not found or self.__class__ in needed:
  5146.             ret = self.mysummary()
  5147.             if type(ret) is tuple:
  5148.                 ret,n = ret
  5149.                 needed += n
  5150.         if ret or needed:
  5151.             found = 1
  5152.         if not ret:
  5153.             ret = self.__class__.__name__
  5154.         ret = "%s%s" % (ret,s)
  5155.         if intern:
  5156.             return found,ret,needed
  5157.         else:
  5158.             return ret
  5159.     
  5160.     def lastlayer(self,layer=None):
  5161.         """Returns the uppest layer of the packet"""
  5162.         return self.payload.lastlayer(self)
  5163.  
  5164.     def decode_payload_as(self,cls):
  5165.         """Reassembles the payload and decode it using another packet class"""
  5166.         s = str(self.payload)
  5167.         self.payload = cls(s)
  5168.  
  5169.     def libnet(self):
  5170.         """Not ready yet. Should give the necessary C code that interfaces with libnet to recreate the packet"""
  5171.         print "libnet_build_%s(" % self.__class__.name.lower()
  5172.         det = self.__class__(str(self))
  5173.         for f in self.fields_desc:
  5174.             val = getattr(det, f.name)
  5175.             if val is None:
  5176.                 val = 0
  5177.             elif type(val) is int:
  5178.                 val = str(val)
  5179.             else:
  5180.                 val = '"%s"' % str(val)
  5181.             print "\t%s, \t\t/* %s */" % (val,f.name)
  5182.         print ");"
  5183.     def command(self):
  5184.         """Returns a string representing the command you have to type to obtain the same packet"""
  5185.         f = []
  5186.         for fn,fv in self.fields.items():
  5187.             if isinstance(fv, Packet):
  5188.                 fv = fv.command()
  5189.             else:
  5190.                 fv = repr(fv)
  5191.             f.append("%s=%s" % (fn, fv))
  5192.         c = "%s(%s)" % (self.__class__.__name__, ", ".join(f))
  5193.         pc = self.payload.command()
  5194.         if pc:
  5195.             c += "/"+pc
  5196.         return c                    
  5197.                        
  5198.     
  5199.         
  5200.  
  5201. class NoPayload(Packet,object):
  5202.     def __new__(cls, *args, **kargs):
  5203.         singl = cls.__dict__.get("__singl__")
  5204.         if singl is None:
  5205.             cls.__singl__ = singl = object.__new__(cls)
  5206.             Packet.__init__(singl, *args, **kargs)
  5207.         return singl
  5208.     def __init__(self, *args, **kargs):
  5209.         pass
  5210.     def dissection_done(self,pkt):
  5211.         return
  5212.     def add_payload(self, payload):
  5213.         raise Exception("Can't add payload to NoPayload instance")
  5214.     def remove_payload(self):
  5215.         pass
  5216.     def add_underlayer(self,underlayer):
  5217.         pass
  5218.     def remove_underlayer(self,other):
  5219.         pass
  5220.     def copy(self):
  5221.         return self
  5222.     def __repr__(self):
  5223.         return ""
  5224.     def __str__(self):
  5225.         return ""
  5226.     def build(self, internal=0):
  5227.         return ""
  5228.     def build_ps(self, internal=0):
  5229.         return "",[]
  5230.     def __getattr__(self, attr):
  5231.         if attr in self.__dict__:
  5232.             return self.__dict__[attr]
  5233.         elif attr in self.__class__.__dict__:
  5234.             return self.__class__.__dict__[attr]
  5235.         else:
  5236.             raise AttributeError, attr
  5237.     def hide_defaults(self):
  5238.         pass
  5239.     def __iter__(self):
  5240.         return iter([])
  5241.     def __eq__(self, other):
  5242.         if isinstance(other, NoPayload):
  5243.             return True
  5244.         return False
  5245.     def hashret(self):
  5246.         return ""
  5247.     def answers(self, other):
  5248.         return isinstance(other, NoPayload) or isinstance(other, Padding)
  5249.     def haslayer(self, cls):
  5250.         return 0
  5251.     def getlayer(self, cls, nb=1, _track=None):
  5252.         if _track is not None:
  5253.             _track.append(nb)
  5254.         return None
  5255.     def show(self, indent=3, lvl="", label_lvl=""):
  5256.         pass
  5257.     def sprintf(self, fmt, relax):
  5258.         if relax:
  5259.             return "??"
  5260.         else:
  5261.             raise Exception("Format not found [%s]"%fmt)
  5262.     def summary(self, intern=0):
  5263.         return 0,"",[]
  5264.     def lastlayer(self,layer):
  5265.         return layer
  5266.     def command(self):
  5267.         return ""
  5268.     
  5269.  
  5270. ####################
  5271. ## packet classes ##
  5272. ####################
  5273.     
  5274.     
  5275. class ChangeDefaultValues(type):
  5276.     def __new__(cls, name, bases, dct):
  5277.         default = dct["new_default_values"]
  5278.         fields = None
  5279.         for b in bases:
  5280.             if hasattr(b,"fields_desc"):
  5281.                 fields = b.fields_desc[:]
  5282.                 break
  5283.         if fields is None:
  5284.             raise Exception("No fields_desc in superclasses")
  5285.  
  5286.         del(dct["new_default_values"])
  5287.         new_fields = []
  5288.         for f in fields:
  5289.             if f in default:
  5290.                 f = f.copy()
  5291.                 f.default = default[f]
  5292.             new_fields.append(f)
  5293.         dct["fields_desc"] = new_fields
  5294.         return super(ChangeDefaultValues, cls).__new__(cls, name, bases, dct)
  5295.  
  5296. # Metaclass
  5297. class NewDefaultValues(type):
  5298.     def __new__(cls, name, bases, dct):
  5299.         fields = None
  5300.         for b in bases:
  5301.             if hasattr(b,"fields_desc"):
  5302.                 fields = b.fields_desc[:]
  5303.                 break
  5304.         if fields is None:
  5305.             raise Exception("No fields_desc in superclasses")
  5306.  
  5307.         new_fields = []
  5308.         for f in fields:
  5309.             if f in dct:
  5310.                 f = f.copy()
  5311.                 f.default = dct[f]
  5312.                 del(dct[f])
  5313.             new_fields.append(f)
  5314.         dct["fields_desc"] = new_fields
  5315.         return super(NewDefaultValues, cls).__new__(cls, name, bases, dct)
  5316.  
  5317.             
  5318. class Raw(Packet):
  5319.     name = "Raw"
  5320.     fields_desc = [ StrField("load", "") ]
  5321.     def answers(self, other):
  5322.         return 1
  5323. #        s = str(other)
  5324. #        t = self.load
  5325. #        l = min(len(s), len(t))
  5326. #        return  s[:l] == t[:l]
  5327.         
  5328. class Padding(Raw):
  5329.     name = "Padding"
  5330.     def build(self, internal=0):
  5331.         if internal:
  5332.             return ""
  5333.         else:
  5334.             return Raw.build(self)
  5335.  
  5336. class Ether(Packet):
  5337.     name = "Ethernet"
  5338.     fields_desc = [ DestMACField("dst"),
  5339.                     SourceMACField("src"),
  5340.                     XShortEnumField("type", 0x0000, ETHER_TYPES) ]
  5341.     def hashret(self):
  5342.         return struct.pack("H",self.type)+self.payload.hashret()
  5343.     def answers(self, other):
  5344.         if isinstance(other,Ether):
  5345.             if self.type == other.type:
  5346.                 return self.payload.answers(other.payload)
  5347.         return 0
  5348.     def mysummary(self):
  5349.         return self.sprintf("%Ether.src% > %Ether.dst% (%Ether.type%)")
  5350.  
  5351. class PPPoE(Packet):
  5352.     name = "PPP over Ethernet"
  5353.     fields_desc = [ BitField("version", 1, 4),
  5354.                     BitField("type", 1, 4),
  5355.                     ByteEnumField("code", 0, {0:"Session"}),
  5356.                     XShortField("sessionid", 0x0),
  5357.                     ShortField("len", None) ]
  5358.  
  5359.     def post_build(self,p):
  5360.         if self.len is None:
  5361.             l = len(p)-6
  5362.             p = p[:4]+struct.pack("!H", l)+p[6:]
  5363.         return p
  5364.  
  5365. class PPPoED(PPPoE):
  5366.     name = "PPP over Ethernet Discovery"
  5367.     fields_desc = [ BitField("version", 1, 4),
  5368.                     BitField("type", 1, 4),
  5369.                     ByteEnumField("code", 0x09, {0x09:"PADI",0x07:"PADO",0x19:"PADR",0x65:"PADS",0xa7:"PADT"}),
  5370.                     XShortField("sessionid", 0x0),
  5371.                     ShortField("len", None) ]
  5372.  
  5373. class Dot3(Packet):
  5374.     name = "802.3"
  5375.     fields_desc = [ MACField("dst", ETHER_BROADCAST),
  5376.                     MACField("src", ETHER_ANY),
  5377.                     LenField("len", None, "H") ]
  5378.     def extract_padding(self,s):
  5379.         l = self.len
  5380.         return s[:l],s[l:]
  5381.     def answers(self, other):
  5382.         if isinstance(other,Dot3):
  5383.             return self.payload.answers(other.payload)
  5384.         return 0
  5385.     def mysummary(self):
  5386.         return "%s > %s" % (self.src, self.dst)
  5387.  
  5388.  
  5389. class LLC(Packet):
  5390.     name = "LLC"
  5391.     fields_desc = [ XByteField("dsap", 0x00),
  5392.                     XByteField("ssap", 0x00),
  5393.                     ByteField("ctrl", 0) ]
  5394.  
  5395.  
  5396. class CookedLinux(Packet):
  5397.     name = "cooked linux"
  5398.     fields_desc = [ ShortEnumField("pkttype",0, {0: "unicast",
  5399.                                                  4:"sent-by-us"}), #XXX incomplete
  5400.                     XShortField("lladdrtype",512),
  5401.                     ShortField("lladdrlen",0),
  5402.                     StrFixedLenField("src","",8),
  5403.                     XShortEnumField("proto",0x800,ETHER_TYPES) ]
  5404.                     
  5405.                                    
  5406.  
  5407. class SNAP(Packet):
  5408.     name = "SNAP"
  5409.     fields_desc = [ X3BytesField("OUI",0x000000),
  5410.                     XShortEnumField("code", 0x000, ETHER_TYPES) ]
  5411.  
  5412.  
  5413. class Dot1Q(Packet):
  5414.     name = "802.1Q"
  5415.     aliastypes = [ Ether ]
  5416.     fields_desc =  [ BitField("prio", 0, 3),
  5417.                      BitField("id", 0, 1),
  5418.                      BitField("vlan", 1, 12),
  5419.                      XShortEnumField("type", 0x0000, ETHER_TYPES) ]
  5420.     def answers(self, other):
  5421.         if isinstance(other,Dot1Q):
  5422.             if ( (self.type == other.type) and
  5423.                  (self.vlan == other.vlan) ):
  5424.                 return self.payload.answers(other.payload)
  5425.         else:
  5426.             return self.payload.answers(other)
  5427.         return 0
  5428.     def mysummary(self):
  5429.         if isinstance(self.underlayer, Ether):
  5430.             return self.underlayer.sprintf("802.1q %Ether.src% > %Ether.dst% (%Dot1Q.type%) vlan %Dot1Q.vlan%")
  5431.         else:
  5432.             return self.sprintf("802.1q (%Dot1Q.type%) vlan %Dot1Q.vlan%")
  5433.  
  5434.  
  5435. class STP(Packet):
  5436.     name = "Spanning Tree Protocol"
  5437.     fields_desc = [ ShortField("proto", 0),
  5438.                     ByteField("version", 0),
  5439.                     ByteField("bpdutype", 0),
  5440.                     ByteField("bpduflags", 0),
  5441.                     ShortField("rootid", 0),
  5442.                     MACField("rootmac", ETHER_ANY),
  5443.                     IntField("pathcost", 0),
  5444.                     ShortField("bridgeid", 0),
  5445.                     MACField("bridgemac", ETHER_ANY),
  5446.                     ShortField("portid", 0),
  5447.                     ShortField("age", 1),
  5448.                     BCDFloatField("maxage", 20),
  5449.                     BCDFloatField("hellotime", 2),
  5450.                     BCDFloatField("fwddelay", 15) ]
  5451.  
  5452.  
  5453. class EAPOL(Packet):
  5454.     name = "EAPOL"
  5455.     fields_desc = [ ByteField("version", 1),
  5456.                     ByteEnumField("type", 0, ["EAP_PACKET", "START", "LOGOFF", "KEY", "ASF"]),
  5457.                     LenField("len", None, "H") ]
  5458.     
  5459.     EAP_PACKET= 0
  5460.     START = 1
  5461.     LOGOFF = 2
  5462.     KEY = 3
  5463.     ASF = 4
  5464.     def extract_padding(self, s):
  5465.         l = self.len
  5466.         return s[:l],s[l:]
  5467.     def hashret(self):
  5468.         return chr(self.type)+self.payload.hashret()
  5469.     def answers(self, other):
  5470.         if isinstance(other,EAPOL):
  5471.             if ( (self.type == self.EAP_PACKET) and
  5472.                  (other.type == self.EAP_PACKET) ):
  5473.                 return self.payload.answers(other.payload)
  5474.         return 0
  5475.     def mysummary(self):
  5476.         return self.sprintf("EAPOL %EAPOL.type%")
  5477.              
  5478.  
  5479. class EAP(Packet):
  5480.     name = "EAP"
  5481.     fields_desc = [ ByteEnumField("code", 4, {1:"REQUEST",2:"RESPONSE",3:"SUCCESS",4:"FAILURE"}),
  5482.                     ByteField("id", 0),
  5483.                     ByteEnumField("type",0, {1:"ID",4:"MD5"}),
  5484.                     ByteField("len",None)]
  5485.     
  5486.     REQUEST = 1
  5487.     RESPONSE = 2
  5488.     SUCCESS = 3
  5489.     FAILURE = 4
  5490.     TYPE_ID = 1
  5491.     TYPE_MD5 = 4
  5492.     def answers(self, other):
  5493.         if isinstance(other,EAP):
  5494.             if self.code == self.REQUEST:
  5495.                 return 0
  5496.             elif self.code == self.RESPONSE:
  5497.                 if ( (other.code == self.REQUEST) and
  5498.                      (other.type == self.type) ):
  5499.                     return 1
  5500.             elif other.code == self.RESPONSE:
  5501.                 return 1
  5502.         return 0            
  5503.     def build(self,internal=0):
  5504.         l = self.len
  5505.         if self.code in [EAP.SUCCESS, EAP.FAILURE]:
  5506.             if l is None:
  5507.                 l = 4
  5508.             return struct.pack("!BBH",
  5509.                                self.code,
  5510.                                self.id,
  5511.                                l)+str(self.payload)
  5512.         else:
  5513.             payl = str(self.payload)
  5514.             if l is None:
  5515.                 l = 5+len(payl)
  5516.             return struct.pack("!BBHB",
  5517.                                self.code,
  5518.                                self.id,
  5519.                                l,
  5520.                                self.type)+payl
  5521.              
  5522.  
  5523. class ARP(Packet):
  5524.     name = "ARP"
  5525.     fields_desc = [ XShortField("hwtype", 0x0001),
  5526.                     XShortEnumField("ptype",  0x0800, ETHER_TYPES),
  5527.                     ByteField("hwlen", 6),
  5528.                     ByteField("plen", 4),
  5529.                     ShortEnumField("op", 1, {"who-has":1, "is-at":2, "RARP-req":3, "RARP-rep":4, "Dyn-RARP-req":5, "Dyn-RAR-rep":6, "Dyn-RARP-err":7, "InARP-req":8, "InARP-rep":9}),
  5530.                     ARPSourceMACField("hwsrc"),
  5531.                     SourceIPField("psrc","pdst"),
  5532.                     MACField("hwdst", ETHER_ANY),
  5533.                     IPField("pdst", "0.0.0.0") ]
  5534.     who_has = 1
  5535.     is_at = 2
  5536.     def answers(self, other):
  5537.         if isinstance(other,ARP):
  5538.             if ( (self.op == self.is_at) and
  5539.                  (other.op == self.who_has) and
  5540.                  (self.psrc == other.pdst) ):
  5541.                 return 1
  5542.         return 0
  5543.     def extract_padding(self, s):
  5544.         return "",s
  5545.     def mysummary(self):
  5546.         if self.op == self.is_at:
  5547.             return "ARP is at %s says %s" % (self.hwsrc, self.psrc)
  5548.         elif self.op == self.who_has:
  5549.             return "ARP who has %s says %s" % (self.pdst, self.psrc)
  5550.         else:
  5551.             return "ARP %ARP.op% %ARP.psrc% > %ARP.pdst%"
  5552.                  
  5553.  
  5554. class IP(Packet, IPTools):
  5555.     name = "IP"
  5556.     fields_desc = [ BitField("version" , 4 , 4),
  5557.                     BitField("ihl", None, 4),
  5558.                     XByteField("tos", 0),
  5559.                     ShortField("len", None),
  5560.                     ShortField("id", 1),
  5561.                     FlagsField("flags", 0, 3, ["MF","DF","evil"]),
  5562.                     BitField("frag", 0, 13),
  5563.                     ByteField("ttl", 64),
  5564.                     ByteEnumField("proto", 0, IP_PROTOS),
  5565.                     XShortField("chksum", None),
  5566.                     #IPField("src", "127.0.0.1"),
  5567.                     Emph(SourceIPField("src","dst")),
  5568.                     Emph(IPField("dst", "127.0.0.1")),
  5569.                     IPoptionsField("options", "") ]
  5570.     def post_build(self, p):
  5571.         ihl = self.ihl
  5572.         if ihl is None:
  5573.             ihl = 5+((len(self.options)+3)/4)
  5574.             p = chr((self.version<<4) | ihl&0x0f)+p[1:]
  5575.         if self.len is None:
  5576.             l = len(p)
  5577.             p = p[:2]+struct.pack("!H", l)+p[4:]
  5578.         if self.chksum is None:
  5579.             ck = checksum(p[:ihl*4])
  5580.             p = p[:10]+chr(ck>>8)+chr(ck&0xff)+p[12:]
  5581.         return p
  5582.  
  5583.     def extract_padding(self, s):
  5584.         l = self.len - (self.ihl << 2)
  5585.         return s[:l],s[l:]
  5586.  
  5587.     def send(self, s, slp=0):
  5588.         for p in self:
  5589.             try:
  5590.                 s.sendto(str(p), (p.dst,0))
  5591.             except socket.error, msg:
  5592.                 log_runtime.error(msg)
  5593.             if slp:
  5594.                 time.sleep(slp)
  5595.     def hashret(self):
  5596.         if ( (self.proto == socket.IPPROTO_ICMP)
  5597.              and (isinstance(self.payload, ICMP))
  5598.              and (self.payload.type in [3,4,5,11,12]) ):
  5599.             return self.payload.payload.hashret()
  5600.         else:
  5601.             if conf.checkIPsrc and conf.checkIPaddr:
  5602.                 return strxor(inet_aton(self.src),inet_aton(self.dst))+struct.pack("B",self.proto)+self.payload.hashret()
  5603.             else:
  5604.                 return struct.pack("B", self.proto)+self.payload.hashret()
  5605.     def answers(self, other):
  5606.         if not isinstance(other,IP):
  5607.             return 0
  5608.         if conf.checkIPaddr and (self.dst != other.src):
  5609.             return 0
  5610.         if ( (self.proto == socket.IPPROTO_ICMP) and
  5611.              (isinstance(self.payload, ICMP)) and
  5612.              (self.payload.type in [3,4,5,11,12]) ):
  5613.             # ICMP error message
  5614.             return self.payload.payload.answers(other)
  5615.  
  5616.         else:
  5617.             if ( (conf.checkIPaddr and (self.src != other.dst)) or
  5618.                  (self.proto != other.proto) ):
  5619.                 return 0
  5620.             return self.payload.answers(other.payload)
  5621.     def mysummary(self):
  5622.         return self.sprintf("%IP.src% > %IP.dst% %IP.proto%")
  5623.                  
  5624.     
  5625.  
  5626. class TCP(Packet):
  5627.     name = "TCP"
  5628.     fields_desc = [ ShortEnumField("sport", 20, TCP_SERVICES),
  5629.                     ShortEnumField("dport", 80, TCP_SERVICES),
  5630.                     IntField("seq", 0),
  5631.                     IntField("ack", 0),
  5632.                     BitField("dataofs", None, 4),
  5633.                     BitField("reserved", 0, 4),
  5634.                     FlagsField("flags", 0x2, 8, "FSRPAUEC"),
  5635.                     ShortField("window", 8192),
  5636.                     XShortField("chksum", None),
  5637.                     ShortField("urgptr", 0),
  5638.                     TCPOptionsField("options", {}) ]
  5639.     def post_build(self, p):
  5640.         dataofs = self.dataofs
  5641.         if dataofs is None:
  5642.             dataofs = 5+((len(self.fieldtype["options"].i2m(self,self.options))+3)/4)
  5643.             p = p[:12]+chr((dataofs << 4) | ord(p[12])&0x0f)+p[13:]
  5644.         if self.chksum is None:
  5645.             if isinstance(self.underlayer, IP):
  5646.                 psdhdr = struct.pack("!4s4sHH",
  5647.                                      inet_aton(self.underlayer.src),
  5648.                                      inet_aton(self.underlayer.dst),
  5649.                                      self.underlayer.proto,
  5650.                                      len(p))
  5651.                 ck=checksum(psdhdr+p)
  5652.                 p = p[:16]+struct.pack("!H", ck)+p[18:]
  5653.             elif isinstance(self.underlayer, IPv6) or isinstance(self.underlayer, _IPv6OptionHeader):
  5654.                 ck = in6_chksum(socket.IPPROTO_TCP, self.underlayer, p)
  5655.                 p = p[:16]+struct.pack("!H", ck)+p[18:]
  5656.             else:
  5657.                 warning("No IP underlayer to compute checksum. Leaving null.")
  5658.         return p
  5659.     def hashret(self):
  5660.         if conf.checkIPsrc:
  5661.             return struct.pack("H",self.sport ^ self.dport)+self.payload.hashret()
  5662.         else:
  5663.             return self.payload.hashret()
  5664.     def answers(self, other):
  5665.         if not isinstance(other, TCP):
  5666.             return 0
  5667.         if conf.checkIPsrc:
  5668.             if not ((self.sport == other.dport) and
  5669.                     (self.dport == other.sport)):
  5670.                 return 0
  5671.         if (abs(other.seq-self.ack) > 2+len(other.payload)):
  5672.             return 0
  5673.         return 1
  5674.     def mysummary(self):
  5675.         if isinstance(self.underlayer, IP):
  5676.             return self.underlayer.sprintf("TCP %IP.src%:%TCP.sport% > %IP.dst%:%TCP.dport% %TCP.flags%")
  5677.         elif isinstance(self.underlayer, IPv6):
  5678.             return self.underlayer.sprintf("TCP %IPv6.src%:%TCP.sport% > %IPv6.dst%:%TCP.dport% %TCP.flags%")
  5679.         else:
  5680.             return self.sprintf("TCP %TCP.sport% > %TCP.dport% %TCP.flags%")
  5681.  
  5682. class UDP(Packet):
  5683.     name = "UDP"
  5684.     fields_desc = [ ShortEnumField("sport", 53, UDP_SERVICES),
  5685.                     ShortEnumField("dport", 53, UDP_SERVICES),
  5686.                     ShortField("len", None),
  5687.                     XShortField("chksum", None), ]
  5688.     def post_build(self, p):
  5689.         l = self.len
  5690.         if l is None:
  5691.             l = len(p)
  5692.             p = p[:4]+struct.pack("!H",l)+p[6:]
  5693.         if self.chksum is None:
  5694.             if isinstance(self.underlayer, IP):
  5695.                 psdhdr = struct.pack("!4s4sHH",
  5696.                                      inet_aton(self.underlayer.src),
  5697.                                      inet_aton(self.underlayer.dst),
  5698.                                      self.underlayer.proto,
  5699.                                      len(p))
  5700.                 ck=checksum(psdhdr+p)
  5701.                 p = p[:6]+struct.pack("!H", ck)+p[8:]
  5702.             elif isinstance(self.underlayer, IPv6) or isinstance(self.underlayer, _IPv6OptionHeader):
  5703.                 ck = in6_chksum(socket.IPPROTO_UDP, self.underlayer, p)
  5704.                 p = p[:6]+struct.pack("!H", ck)+p[8:]
  5705.             else:
  5706.                 warning("No IP underlayer to compute checksum. Leaving null.")
  5707.         return p
  5708.     def extract_padding(self, s):
  5709.         l = self.len - 8
  5710.         return s[:l],s[l:]
  5711.     def hashret(self):
  5712.         if conf.checkIPsrc:
  5713.             return struct.pack("H",self.sport ^ self.dport)+self.payload.hashret()
  5714.         else:
  5715.             return self.payload.hashret()
  5716.     def answers(self, other):
  5717.         if not isinstance(other, UDP):
  5718.             return 0
  5719.         if conf.checkIPsrc:
  5720.             if not ((self.sport == other.dport) and
  5721.                     (self.dport == other.sport)):
  5722.                 return 0
  5723.     return self.payload.answers(other.payload)
  5724.     def mysummary(self):
  5725.         if isinstance(self.underlayer, IP):
  5726.             return self.underlayer.sprintf("UDP %IP.src%:%UDP.sport% > %IP.dst%:%UDP.dport%")
  5727.         elif isinstance(self.underlayer, IPv6):
  5728.             return self.underlayer.sprintf("UDP %IPv6.src%:%UDP.sport% > %IPv6.dst%:%UDP.dport%")
  5729.         else:
  5730.             return self.sprintf("UDP %UDP.sport% > %UDP.dport%")    
  5731.  
  5732. icmptypes = { 0 : "echo-reply",
  5733.               3 : "dest-unreach",
  5734.               4 : "source-quench",
  5735.               5 : "redirect",
  5736.               8 : "echo-request",
  5737.               9 : "router-advertisement",
  5738.               10 : "router-solicitation",
  5739.               11 : "time-exceeded",
  5740.               12 : "parameter-problem",
  5741.               13 : "timestamp-request",
  5742.               14 : "timestamp-reply",
  5743.               15 : "information-request",
  5744.               16 : "information-response",
  5745.               17 : "address-mask-request",
  5746.               18 : "address-mask-reply" }
  5747.  
  5748. class ICMP(Packet):
  5749.     name = "ICMP"
  5750.     fields_desc = [ ByteEnumField("type",8, icmptypes),
  5751.                     ByteField("code",0),
  5752.                     XShortField("chksum", None),
  5753.                     XShortField("id",0),
  5754.                     XShortField("seq",0) ]
  5755.     def post_build(self, p):
  5756.         if self.chksum is None:
  5757.             ck = checksum(p)
  5758.             p = p[:2]+chr(ck>>8)+chr(ck&0xff)+p[4:]
  5759.         return p
  5760.     
  5761.     def hashret(self):
  5762.         return struct.pack("HH",self.id,self.seq)+self.payload.hashret()
  5763.     def answers(self, other):
  5764.         if not isinstance(other,ICMP):
  5765.             return 0
  5766.         if ( (other.type,self.type) in [(8,0),(13,14),(15,16),(17,18)] and
  5767.              self.id == other.id and
  5768.              self.seq == other.seq ):
  5769.             return 1
  5770.         return 0
  5771.  
  5772.     def guess_payload_class(self, payload):
  5773.         if self.type in [3,4,5,11,12]:
  5774.             return IPerror
  5775.         else:
  5776.             return None
  5777.     def mysummary(self):
  5778.         if isinstance(self.underlayer, IP):
  5779.             return self.underlayer.sprintf("ICMP %IP.src% > %IP.dst% %ICMP.type% %ICMP.code%")
  5780.         else:
  5781.             return self.sprintf("ICMP %ICMP.type% %ICMP.code%")
  5782.     
  5783.         
  5784.  
  5785.  
  5786.  
  5787. class IPerror(IP):
  5788.     name = "IP in ICMP"
  5789.     def answers(self, other):
  5790.         if not isinstance(other, IP):
  5791.             return 0
  5792.         if not ( ((conf.checkIPsrc == 0) or (self.dst == other.dst)) and
  5793.                  (self.src == other.src) and
  5794.                  ( ((conf.checkIPID == 0)
  5795.                     or (self.id == other.id)
  5796.                     or (conf.checkIPID == 1 and self.id == socket.htons(other.id)))) and
  5797.                  (self.proto == other.proto) ):
  5798.             return 0
  5799.         return self.payload.answers(other.payload)
  5800.     def mysummary(self):
  5801.         return Packet.mysummary(self)
  5802.  
  5803.  
  5804. class TCPerror(TCP):
  5805.     name = "TCP in ICMP"
  5806.     def answers(self, other):
  5807.         if not isinstance(other, TCP):
  5808.             return 0
  5809.         if conf.checkIPsrc:
  5810.             if not ((self.sport == other.sport) and
  5811.                     (self.dport == other.dport)):
  5812.                 return 0
  5813.         if conf.check_TCPerror_seqack:
  5814.             if self.seq is not None:
  5815.                 if self.seq != other.seq:
  5816.                     return 0
  5817.             if self.ack is not None:
  5818.                 if self.ack != other.ack:
  5819.                     return 0
  5820.         return 1
  5821.     def mysummary(self):
  5822.         return Packet.mysummary(self)
  5823.  
  5824.  
  5825. class UDPerror(UDP):
  5826.     name = "UDP in ICMP"
  5827.     def answers(self, other):
  5828.         if not isinstance(other, UDP):
  5829.             return 0
  5830.         if conf.checkIPsrc:
  5831.             if not ((self.sport == other.sport) and
  5832.                     (self.dport == other.dport)):
  5833.                 return 0
  5834.         return 1
  5835.     def mysummary(self):
  5836.         return Packet.mysummary(self)
  5837.  
  5838.                     
  5839.  
  5840. class ICMPerror(ICMP):
  5841.     name = "ICMP in ICMP"
  5842.     def answers(self, other):
  5843.         if not isinstance(other,ICMP):
  5844.             return 0
  5845.         if not ((self.type == other.type) and
  5846.                 (self.code == other.code)):
  5847.             return 0
  5848.         if self.code in [0,8,13,14,17,18]:
  5849.             if (self.id == other.id and
  5850.                 self.seq == other.seq):
  5851.                 return 1
  5852.             else:
  5853.                 return 0
  5854.         else:
  5855.             return 1
  5856.     def mysummary(self):
  5857.         return Packet.mysummary(self)
  5858.  
  5859. class IPv6(Packet):
  5860.     """See http://namabiiru.hongo.wide.ad.jp/scapy6"""
  5861.     name = "IPv6 not implemented here." 
  5862.     def __init__(self, *args, **kargs):
  5863.         log_interactive.error(self.name)
  5864.     def __repr__(self):
  5865.         return "<IPv6: ERROR not implemented>"
  5866.     
  5867. class _IPv6OptionHeader(Packet):
  5868.     """See http://namabiiru.hongo.wide.ad.jp/scapy6"""
  5869.     name = "IPv6 not implemented here."
  5870.     def __init__(self, *args, **kargs):
  5871.         log_interactive.error(self.name)
  5872.     def __repr__(self):
  5873.         return "<IPv6: ERROR not implemented>"
  5874.                 
  5875. class PPP(Packet):
  5876.     name = "PPP Link Layer"
  5877.     fields_desc = [ ShortEnumField("proto", 0x0021, {0x0021: "IP",
  5878.                                                      0xc021: "LCP"} ) ]
  5879.             
  5880.         
  5881. class DNS(Packet):
  5882.     name = "DNS"
  5883.     fields_desc = [ ShortField("id",0),
  5884.                     BitField("qr",0, 1),
  5885.                     BitEnumField("opcode", 0, 4, {0:"QUERY",1:"IQUERY",2:"STATUS"}),
  5886.                     BitField("aa", 0, 1),
  5887.                     BitField("tc", 0, 1),
  5888.                     BitField("rd", 0, 1),
  5889.                     BitField("ra", 0 ,1),
  5890.                     BitField("z", 0, 3),
  5891.                     BitEnumField("rcode", 0, 4, {0:"ok", 1:"format-error", 2:"server-failure", 3:"name-error", 4:"not-implemented", 5:"refused"}),
  5892.                     DNSRRCountField("qdcount", None, "qd"),
  5893.                     DNSRRCountField("ancount", None, "an"),
  5894.                     DNSRRCountField("nscount", None, "ns"),
  5895.                     DNSRRCountField("arcount", None, "ar"),
  5896.                     DNSQRField("qd", "qdcount"),
  5897.                     DNSRRField("an", "ancount"),
  5898.                     DNSRRField("ns", "nscount"),
  5899.                     DNSRRField("ar", "arcount",0) ]
  5900.     def answers(self, other):
  5901.         return (isinstance(other, DNS)
  5902.                 and self.id == other.id
  5903.                 and self.qr == 1
  5904.                 and other.qr == 0)
  5905.         
  5906.     def mysummary(self):
  5907.         type = ["Qry","Ans"][self.qr]
  5908.         name = ""
  5909.         if self.qr:
  5910.             type = "Ans"
  5911.             if self.ancount > 0:
  5912.                 name = ' "%s"' % self.an.rdata
  5913.         else:
  5914.             type = "Qry"
  5915.             if self.qdcount > 0:
  5916.                 name = ' "%s"' % self.qd.qname
  5917.         return 'DNS %s%s ' % (type, name)
  5918.  
  5919. dnstypes = { 0:"ANY", 255:"ALL",
  5920.              1:"A", 2:"NS", 3:"MD", 4:"MD", 5:"CNAME", 6:"SOA", 7: "MB", 8:"MG",
  5921.              9:"MR",10:"NULL",11:"WKS",12:"PTR",13:"HINFO",14:"MINFO",15:"MX",16:"TXT",
  5922.              17:"RP",18:"AFSDB",28:"AAAA", 33:"SRV",38:"A6",39:"DNAME"}
  5923.  
  5924. dnsqtypes = {251:"IXFR",252:"AXFR",253:"MAILB",254:"MAILA",255:"ALL"}
  5925. dnsqtypes.update(dnstypes)
  5926. dnsclasses =  {1: 'IN',  2: 'CS',  3: 'CH',  4: 'HS',  255: 'ANY'}
  5927.  
  5928.  
  5929. class DNSQR(Packet):
  5930.     name = "DNS Question Record"
  5931.     show_indent=0
  5932.     fields_desc = [ DNSStrField("qname",""),
  5933.                     ShortEnumField("qtype", 1, dnsqtypes),
  5934.                     ShortEnumField("qclass", 1, dnsclasses) ]
  5935.                     
  5936.                     
  5937.  
  5938. class DNSRR(Packet):
  5939.     name = "DNS Resource Record"
  5940.     show_indent=0
  5941.     fields_desc = [ DNSStrField("rrname",""),
  5942.                     ShortEnumField("type", 1, dnstypes),
  5943.                     ShortEnumField("rclass", 1, dnsclasses),
  5944.                     IntField("ttl", 0),
  5945.                     RDLenField("rdlen"),
  5946.                     RDataField("rdata", "", "rdlen") ]
  5947.  
  5948. dhcpmagic="c\x82Sc"
  5949.  
  5950.  
  5951. class BOOTP(Packet):
  5952.     name = "BOOTP"
  5953.     fields_desc = [ ByteEnumField("op",1, {1:"BOOTREQUEST", 2:"BOOTREPLY"}),
  5954.                     ByteField("htype",1),
  5955.                     ByteField("hlen",6),
  5956.                     ByteField("hops",0),
  5957.                     IntField("xid",0),
  5958.                     ShortField("secs",0),
  5959.                     FlagsField("flags", 0, 16, "???????????????B"),
  5960.                     IPField("ciaddr","0.0.0.0"),
  5961.                     IPField("yiaddr","0.0.0.0"),
  5962.                     IPField("siaddr","0.0.0.0"),
  5963.                     IPField("giaddr","0.0.0.0"),
  5964.                     Field("chaddr","", "16s"),
  5965.                     Field("sname","","64s"),
  5966.                     Field("file","","128s"),
  5967.                     StrField("options","") ]
  5968.     def guess_payload_class(self, payload):
  5969.     if self.options[:len(dhcpmagic)] == dhcpmagic:
  5970.         return DHCP
  5971.     else:
  5972.             return Packet.guess_payload_class(self, payload)
  5973.     def extract_padding(self,s):
  5974.     if self.options[:len(dhcpmagic)] == dhcpmagic:
  5975.         # set BOOTP options to DHCP magic cookie and make rest a payload of DHCP options
  5976.         payload = self.options[len(dhcpmagic):]
  5977.         self.options = self.options[:len(dhcpmagic)]
  5978.         return payload, None
  5979.     else:
  5980.         return "", None
  5981.     def hashret(self):
  5982.     return struct.pack("L", self.xid)
  5983.     def answers(self, other):
  5984.         if not isinstance(other, BOOTP):
  5985.         return 0
  5986.     return self.xid == other.xid
  5987.  
  5988.  
  5989.  
  5990. #DHCP_UNKNOWN, DHCP_IP, DHCP_IPLIST, DHCP_TYPE \
  5991. #= range(4)
  5992. #
  5993.  
  5994. DHCPTypes = {
  5995.         1: "discover",
  5996.         2: "offer",
  5997.         3: "decline",
  5998.         4: "ack",
  5999.         5: "nak",
  6000.         6: "release",
  6001.         7: "inform"
  6002.         }
  6003. #
  6004. #DHCPOptions = (
  6005. #        {
  6006. #            1: ("subnet-mask", DHCP_IP),
  6007. #            3: ("routers", DHCP_IPLIST),
  6008. #            53: ("message-type", DHCP_MESSAGE_TYPE),
  6009. #            55: ("request-list", DHCP_REQUEST_LIST
  6010. #            },
  6011. #        {
  6012. #            "subnet-mask": (1, DHCP_IP)
  6013. #            "routers": (3, DHCP_IPLIST)
  6014. #            "message-type": (53, DHCP_TYPE)
  6015. #            } )
  6016.  
  6017. DHCPOptions = {
  6018.     0: "pad",
  6019.     1: IPField("subnet_mask", "0.0.0.0"),
  6020.     2: "time_zone",
  6021.     3: IPField("router","0.0.0.0"),
  6022.     4: IPField("time_server","0.0.0.0"),
  6023.     5: IPField("IEN_name_server","0.0.0.0"),
  6024.     6: IPField("name_server","0.0.0.0"),
  6025.     7: IPField("log_server","0.0.0.0"),
  6026.     8: IPField("cookie_server","0.0.0.0"),
  6027.     9: IPField("lpr_server","0.0.0.0"),
  6028.     12: "hostname",
  6029.     14: "dump_path",
  6030.     15: "domain",
  6031.     17: "root_disk_path",
  6032.     22: "max_dgram_reass_size",
  6033.     23: "default_ttl",
  6034.     24: "pmtu_timeout",
  6035.     28: IPField("broadcast_address","0.0.0.0"),
  6036.     35: "arp_cache_timeout",
  6037.     36: "ether_or_dot3",
  6038.     37: "tcp_ttl",
  6039.     38: "tcp_keepalive_interval",
  6040.     39: "tcp_keepalive_garbage",
  6041.     40: "NIS_domain",
  6042.     41: IPField("NIS_server","0.0.0.0"),
  6043.     42: IPField("NTP_server","0.0.0.0"),
  6044.     43: "vendor_specific",
  6045.     44: IPField("NetBIOS_server","0.0.0.0"),
  6046.     45: IPField("NetBIOS_dist_server","0.0.0.0"),
  6047.     51: IntField("lease_time", 43200),
  6048.     54: IPField("server_id","0.0.0.0"),
  6049.     55: "param_req_list",
  6050.     57: ShortField("max_dhcp_size", 1500),
  6051.     58: IntField("renewal_time", 21600),
  6052.     59: IntField("rebinding_time", 37800),
  6053.     60: "vendor_class_id",
  6054.     
  6055.     
  6056.     64: "NISplus_domain",
  6057.     65: IPField("NISplus_server","0.0.0.0"),
  6058.     69: IPField("SMTP_server","0.0.0.0"),
  6059.     70: IPField("POP3_server","0.0.0.0"),
  6060.     71: IPField("NNTP_server","0.0.0.0"),
  6061.     72: IPField("WWW_server","0.0.0.0"),
  6062.     73: IPField("Finger_server","0.0.0.0"),
  6063.     74: IPField("IRC_server","0.0.0.0"),
  6064.     75: IPField("StreetTalk_server","0.0.0.0"),
  6065.     76: "StreetTalk_Dir_Assistance",
  6066.     53: ByteEnumField("message-type", 1, DHCPTypes),
  6067.     #            55: DHCPRequestListField("request-list"),
  6068.     255: "end"
  6069.     }
  6070.  
  6071. DHCPRevOptions = {}
  6072.  
  6073. for k,v in DHCPOptions.iteritems():
  6074.     if type(v) is str:
  6075.         n = v
  6076.         v = None
  6077.     else:
  6078.         n = str(v)
  6079.     DHCPRevOptions[n] = (k,v)
  6080. del(n)
  6081. del(v)
  6082. del(k)
  6083.     
  6084.     
  6085.  
  6086. #
  6087. #{
  6088. #            "pad": (0, None),
  6089. #            "subnet-mask": (1, IPField("subnet-mask", "0.0.0.0")),
  6090. ##            "routers": (3, IPListField("routers")),
  6091. #            "message-type": (53, ByteEnumField("message-type", 1, DHCPTypes)),
  6092. #            "end": (255, None)
  6093. #            } )
  6094.  
  6095.  
  6096.  
  6097. class DHCPOptionsField(StrField):
  6098.     islist=1
  6099.     def i2repr(self,pkt,x):
  6100.         s = []
  6101.         for v in x:
  6102.             if type(v) is tuple and len(v) == 2:
  6103.                 if  DHCPRevOptions.has_key(v[0]) and isinstance(DHCPRevOptions[v[0]][1],Field):
  6104.                     f = DHCPRevOptions[v[0]][1]
  6105.                     vv = f.i2repr(pkt,v[1])
  6106.                 else:
  6107.                     vv = repr(v[1])
  6108.                 s.append("%s=%s" % (v[0],vv))
  6109.             else:
  6110.                 s.append(str(v))
  6111.         return "[%s]" % (" ".join(s))
  6112.         
  6113.     def getfield(self, pkt, s):
  6114.     #print "getfield s=%s %d" % (s, len(s))
  6115.     return "", self.m2i(pkt, s)
  6116.     def m2i(self, pkt, x):
  6117.     #print "m2i x=%s len=%d" % (x, len(x))
  6118.     opt = []
  6119.     while x:
  6120.         o = ord(x[0])
  6121.         #print "o=%d x=%s len=%d" % (o, x, len(x))
  6122.             if o == 255:
  6123.                 opt.append("end")
  6124.                 x = x[1:]
  6125.                 continue
  6126.             if o == 0:
  6127.                 opt.append("pad")
  6128.                 x = x[1:]
  6129.                 continue
  6130.         if DHCPOptions.has_key(o):
  6131.         f = DHCPOptions[o]
  6132.  
  6133.         if isinstance(f, str):
  6134.                     olen = ord(x[1])
  6135.                     opt.append( (f,x[2:olen+2]) )
  6136.             x = x[olen+2:]
  6137.         else:
  6138.             olen = ord(x[1])
  6139.             left, val = f.getfield(pkt,x[2:olen+2])
  6140. #                    val = f.m2i(pkt,val)
  6141. #            if left:
  6142. #            print "m2i data left left=%s" % left
  6143.             opt.append((f.name, val))
  6144.             x = x[olen+2:]
  6145.         else:
  6146.         olen = ord(x[1])
  6147.         opt.append((o, x[2:olen+2]))
  6148.         x = x[olen+2:]
  6149.     return opt
  6150.     def i2m(self, pkt, x):
  6151.     #print "i2m x=%s" % x
  6152.     s = ""
  6153.     for o in x:
  6154.         if type(o) is tuple and len(o) == 2:
  6155.         name, val = o
  6156.  
  6157.         if isinstance(name, int):
  6158.             onum, oval = name, val
  6159.         elif DHCPRevOptions.has_key(name):
  6160.                     onum, f = DHCPRevOptions[name]
  6161.                     if  f is None:
  6162.                         oval = val
  6163.                     else:
  6164. #                 oval = f.addfield(pkt,"",f.i2m(pkt,f.any2i(pkt,val)))
  6165.                         oval = f.addfield(pkt,"",f.any2i(pkt,val))
  6166.                         
  6167.         else:
  6168.             warning("Unknown field option %s" % name)
  6169.             continue
  6170.  
  6171.         s += chr(onum)
  6172.         s += chr(len(oval))
  6173.         s += oval
  6174.         
  6175.         elif (type(o) is str and DHCPRevOptions.has_key(o) and 
  6176.                   DHCPRevOptions[o][1] == None):
  6177.         s += chr(DHCPRevOptions[o][0])
  6178.             elif type(o) is int:
  6179.                 s += chr(o)
  6180.         else:
  6181.         warning("Malformed option %s" % o)
  6182.     return s
  6183.  
  6184.  
  6185. class DHCP(Packet):
  6186.     name = "DHCP options"
  6187.     fields_desc = [ DHCPOptionsField("options","") ]    
  6188.  
  6189.  
  6190. class Dot11(Packet):
  6191.     name = "802.11"
  6192.     fields_desc = [
  6193.                     BitField("subtype", 0, 4),
  6194.                     BitEnumField("type", 0, 2, ["Management", "Control", "Data", "Reserved"]),
  6195.                     BitField("proto", 0, 2),
  6196.                     FlagsField("FCfield", 0, 8, ["to-DS", "from-DS", "MF", "retry", "pw-mgt", "MD", "wep", "order"]),
  6197.                     ShortField("ID",0),
  6198.                     MACField("addr1", ETHER_ANY),
  6199.                     Dot11Addr2MACField("addr2", ETHER_ANY),
  6200.                     Dot11Addr3MACField("addr3", ETHER_ANY),
  6201.                     LEShortField("SC", 0),
  6202.                     Dot11Addr4MACField("addr4", ETHER_ANY) 
  6203.                     ]
  6204.     def mysummary(self):
  6205.         return self.sprintf("802.11 %Dot11.type% %Dot11.subtype% %Dot11.addr2% > %Dot11.addr1%")
  6206.     def guess_payload_class(self, payload):
  6207.         if self.FCfield & 0x40:
  6208.             return Dot11WEP
  6209.         else:
  6210.             return Packet.guess_payload_class(self, payload)
  6211.     def answers(self, other):
  6212.         if isinstance(other,Dot11):
  6213.             if self.type == 0: # mangement
  6214.                 if self.addr3 != other.addr3:
  6215.                     return0
  6216.                 if (other.subtype,self.subtype) in [(0,1),(2,3),(4,5)]:
  6217.                     return 1
  6218.                 if self.subtype == other.subtype == 11: # auth
  6219.                     return self.payload.answers(other.payload)
  6220.             elif self.type == 1: # control
  6221.                 return 0
  6222.             elif self.type == 2: # data
  6223.                 return self.payload.answers(other.payload)
  6224.             elif self.type == 3: # reserved
  6225.                 return 0
  6226.         return 0
  6227.     def unwep(self, key=None, warn=1):
  6228.         if self.FCfield & 0x40 == 0:
  6229.             if warn:
  6230.                 warning("No WEP to remove")
  6231.             return
  6232.         if  isinstance(self.payload.payload, NoPayload):
  6233.             if key or conf.wepkey:
  6234.                 self.payload.decrypt(key)
  6235.             if isinstance(self.payload.payload, NoPayload):
  6236.                 if warn:
  6237.                     warning("Dot11 can't be decrypted. Check conf.wepkey.")
  6238.                 return
  6239.         self.FCfield &= ~0x40
  6240.         self.payload=self.payload.payload
  6241.  
  6242.  
  6243. capability_list = [ "res8", "res9", "short-slot", "res11",
  6244.                     "res12", "DSSS-OFDM", "res14", "res15",
  6245.                    "ESS", "IBSS", "CFP", "CFP-req",
  6246.                    "privacy", "short-preamble", "PBCC", "agility"]
  6247.  
  6248. reason_code = {0:"reserved",1:"unspec", 2:"auth-expired",
  6249.                3:"deauth-ST-leaving",
  6250.                4:"inactivity", 5:"AP-full", 6:"class2-from-nonauth",
  6251.                7:"class3-from-nonass", 8:"disas-ST-leaving",
  6252.                9:"ST-not-auth"}
  6253.  
  6254. status_code = {0:"success", 1:"failure", 10:"cannot-support-all-cap",
  6255.                11:"inexist-asso", 12:"asso-denied", 13:"algo-unsupported",
  6256.                14:"bad-seq-num", 15:"challenge-failure",
  6257.                16:"timeout", 17:"AP-full",18:"rate-unsupported" }
  6258.  
  6259. class Dot11Beacon(Packet):
  6260.     name = "802.11 Beacon"
  6261.     fields_desc = [ LELongField("timestamp", 0),
  6262.                     LEShortField("beacon_interval", 0x6400),
  6263.                     FlagsField("cap", 0, 16, capability_list) ]
  6264.     
  6265.  
  6266. class Dot11Elt(Packet):
  6267.     name = "802.11 Information Element"
  6268.     fields_desc = [ ByteEnumField("ID", 0, {0:"SSID", 1:"Rates", 2: "FHset", 3:"DSset", 4:"CFset", 5:"TIM", 6:"IBSSset", 16:"challenge",
  6269.                                             42:"ERPinfo", 47:"ERPinfo",50:"ESRates",221:"vendor",68:"reserved"}),
  6270.                     FieldLenField("len", None, "info", "B"),
  6271.                     StrLenField("info", "", "len") ]
  6272.     def mysummary(self):
  6273.         if self.ID == 0:
  6274.             return "SSID=%s"%repr(self.info),[Dot11]
  6275.         else:
  6276.             return ""
  6277.  
  6278. class Dot11ATIM(Packet):
  6279.     name = "802.11 ATIM"
  6280.  
  6281. class Dot11Disas(Packet):
  6282.     name = "802.11 Disassociation"
  6283.     fields_desc = [ ShortEnumField("reason", 1, reason_code) ]
  6284.  
  6285. class Dot11AssoReq(Packet):
  6286.     name = "802.11 Association Request"
  6287.     fields_desc = [ FlagsField("cap", 0, 16, capability_list),
  6288.                     ShortField("listen_interval", 0xc800) ]
  6289.  
  6290.  
  6291. class Dot11AssoResp(Packet):
  6292.     name = "802.11 Association Response"
  6293.     fields_desc = [ FlagsField("cap", 0, 16, capability_list),
  6294.                     ShortField("status", 0),
  6295.                     ShortField("AID", 0) ]
  6296.  
  6297. class Dot11ReassoReq(Packet):
  6298.     name = "802.11 Reassociation Request"
  6299.     fields_desc = [ FlagsField("cap", 0, 16, capability_list),
  6300.                     MACField("current_AP", ETHER_ANY),
  6301.                     ShortField("listen_interval", 0xc800) ]
  6302.  
  6303.  
  6304. class Dot11ReassoResp(Dot11AssoResp):
  6305.     name = "802.11 Reassociation Response"
  6306.  
  6307. class Dot11ProbeReq(Packet):
  6308.     name = "802.11 Probe Request"
  6309.     
  6310. class Dot11ProbeResp(Packet):
  6311.     name = "802.11 Probe Response"
  6312.     fields_desc = [ LongField("timestamp", 0),
  6313.                     ShortField("beacon_interval", 0x6400),
  6314.                     FlagsField("cap", 0, 16, capability_list) ]
  6315.     
  6316. class Dot11Auth(Packet):
  6317.     name = "802.11 Authentication"
  6318.     fields_desc = [ ShortEnumField("algo", 0, ["open", "sharedkey"]),
  6319.                     LEShortField("seqnum", 0),
  6320.                     ShortEnumField("status", 0, status_code) ]
  6321.     def answers(self, other):
  6322.         if self.seqnum == other.seqnum+1:
  6323.             return 1
  6324.         return 0
  6325.  
  6326. class Dot11Deauth(Packet):
  6327.     name = "802.11 Deauthentication"
  6328.     fields_desc = [ ShortEnumField("reason", 1, reason_code) ]
  6329.  
  6330.  
  6331.  
  6332. class Dot11WEP(Packet):
  6333.     name = "802.11 WEP packet"
  6334.     fields_desc = [ StrFixedLenField("iv", "", 3),
  6335.                     ByteField("keyid", 0),
  6336.                     StrField("wepdata",None,remain=4),
  6337.                     IntField("icv",None) ]
  6338.  
  6339.     def post_dissect(self, s):
  6340. #        self.icv, = struct.unpack("!I",self.wepdata[-4:])
  6341. #        self.wepdata = self.wepdata[:-4]
  6342.         self.decrypt()
  6343.  
  6344.     def do_build(self):
  6345.         p=""
  6346.         for f in self.fields_desc:
  6347.             p = f.addfield(self, p, self.__getattr__(f))
  6348.         if self.wepdata is None:
  6349.             p = p+self.payload.build(internal=1)
  6350.         return p
  6351.  
  6352.     def post_build(self,p):
  6353.         if self.wepdata is None:
  6354.             key = conf.wepkey
  6355.             if key:
  6356.                 pl = p[8:]
  6357.                 if self.icv is None:
  6358.                     pl += struct.pack("<I",crc32(0xffffffffL,pl)^0xffffffffL)
  6359.                     icv = ""
  6360.                 else:
  6361.                     icv = p[4:8]
  6362.                 c = ARC4.new(self.iv+key)
  6363.                 p = p[:4]+c.encrypt(pl)+icv
  6364.             else:
  6365.                 warning("No WEP key set (conf.wepkey).. strange results expected..")
  6366.         return p
  6367.             
  6368.  
  6369.     def decrypt(self,key=None):
  6370.         if key is None:
  6371.             key = conf.wepkey
  6372.         if key:
  6373.             c = ARC4.new(self.iv+key)
  6374.             self.add_payload(LLC(c.decrypt(self.wepdata)))
  6375.                     
  6376.  
  6377.  
  6378. class PrismHeader(Packet):
  6379.     """ iwpriv wlan0 monitor 3 """
  6380.     name = "Prism header"
  6381.     fields_desc = [ LEIntField("msgcode",68),
  6382.                     LEIntField("len",144),
  6383.                     StrFixedLenField("dev","",16),
  6384.                     LEIntField("hosttime_did",0),
  6385.                   LEShortField("hosttime_status",0),
  6386.                   LEShortField("hosttime_len",0),
  6387.                     LEIntField("hosttime",0),
  6388.                     LEIntField("mactime_did",0),
  6389.                   LEShortField("mactime_status",0),
  6390.                   LEShortField("mactime_len",0),
  6391.                     LEIntField("mactime",0),
  6392.                     LEIntField("channel_did",0),
  6393.                   LEShortField("channel_status",0),
  6394.                   LEShortField("channel_len",0),
  6395.                     LEIntField("channel",0),
  6396.                     LEIntField("rssi_did",0),
  6397.                   LEShortField("rssi_status",0),
  6398.                   LEShortField("rssi_len",0),
  6399.                     LEIntField("rssi",0),
  6400.                     LEIntField("sq_did",0),
  6401.                   LEShortField("sq_status",0),
  6402.                   LEShortField("sq_len",0),
  6403.                     LEIntField("sq",0),
  6404.                     LEIntField("signal_did",0),
  6405.                   LEShortField("signal_status",0),
  6406.                   LEShortField("signal_len",0),
  6407.               LESignedIntField("signal",0),
  6408.                     LEIntField("noise_did",0),
  6409.                   LEShortField("noise_status",0),
  6410.                   LEShortField("noise_len",0),
  6411.                     LEIntField("noise",0),
  6412.                     LEIntField("rate_did",0),
  6413.                   LEShortField("rate_status",0),
  6414.                   LEShortField("rate_len",0),
  6415.                     LEIntField("rate",0),
  6416.                     LEIntField("istx_did",0),
  6417.                   LEShortField("istx_status",0),
  6418.                   LEShortField("istx_len",0),
  6419.                     LEIntField("istx",0),
  6420.                     LEIntField("frmlen_did",0),
  6421.                   LEShortField("frmlen_status",0),
  6422.                   LEShortField("frmlen_len",0),
  6423.                     LEIntField("frmlen",0),
  6424.                     ]
  6425.  
  6426.  
  6427.  
  6428. class HSRP(Packet):
  6429.     name = "HSRP"
  6430.     fields_desc = [
  6431.         ByteField("version", 0),
  6432.         ByteEnumField("opcode", 0, { 0:"Hello"}),
  6433.         ByteEnumField("state", 16, { 16:"Active"}),
  6434.         ByteField("hellotime", 3),
  6435.         ByteField("holdtime", 10),
  6436.         ByteField("priority", 120),
  6437.         ByteField("group", 1),
  6438.         ByteField("reserved", 0),
  6439.         StrFixedLenField("auth","cisco",8),
  6440.         IPField("virtualIP","192.168.1.1") ]
  6441.         
  6442.  
  6443.  
  6444.         
  6445.         
  6446.  
  6447.  
  6448. class NTP(Packet):
  6449.     # RFC 1769
  6450.     name = "NTP"
  6451.     fields_desc = [ 
  6452.          BitEnumField('leap', 0, 2,
  6453.                       { 0: 'nowarning',
  6454.                         1: 'longminute',
  6455.                         2: 'shortminute',
  6456.                         3: 'notsync'}),
  6457.          BitField('version', 3, 3),
  6458.          BitEnumField('mode', 3, 3,
  6459.                       { 0: 'reserved',
  6460.                         1: 'sym_active',
  6461.                         2: 'sym_passive',
  6462.                         3: 'client',
  6463.                         4: 'server',
  6464.                         5: 'broadcast',
  6465.                         6: 'control',
  6466.                         7: 'private'}),
  6467.          BitField('stratum', 2, 8),
  6468.          BitField('poll', 0xa, 8),          ### XXX : it's a signed int
  6469.          BitField('precision', 0, 8),       ### XXX : it's a signed int
  6470.          FloatField('delay', 0, 32),
  6471.          FloatField('dispersion', 0, 32),
  6472.          IPField('id', "127.0.0.1"),
  6473.          TimeStampField('ref', 0, 64),
  6474.          TimeStampField('orig', -1, 64),  # -1 means current time
  6475.          TimeStampField('recv', 0, 64),
  6476.          TimeStampField('sent', -1, 64) 
  6477.          ]
  6478.     def mysummary(self):
  6479.         return self.sprintf("NTP v%ir,NTP.version%, %NTP.mode%")
  6480.  
  6481.  
  6482. class GRE(Packet):
  6483.     name = "GRE"
  6484.     fields_desc = [ BitField("chksumpresent",0,1),
  6485.                     BitField("reserved0",0,12),
  6486.                     BitField("version",0,3),
  6487.                     XShortEnumField("proto", 0x0000, ETHER_TYPES),
  6488.                     ConditionalField(XShortField("chksum",None),"chksumpresent",lambda x:x==1),
  6489.                     ConditionalField(XShortField("reserved1",None),"chksumpresent",lambda x:x==1),
  6490.                     ]
  6491.     def post_build(self, p):
  6492.         if self.chksumpresent and self.chksum is None:
  6493.             c = checksum(p)
  6494.             p = p[:4]+chr((c>>8)&0xff)+chr(c&0xff)+p[6:]
  6495.         return p
  6496.             
  6497.  
  6498. class Radius(Packet):
  6499.     name = "Radius"
  6500.     fields_desc = [ ByteEnumField("code", 1, {1: "Access-Request",
  6501.                                               2: "Access-Accept",
  6502.                                               3: "Access-Reject",
  6503.                                               4: "Accounting-Request",
  6504.                                               5: "Accounting-Accept",
  6505.                                               6: "Accounting-Status",
  6506.                                               7: "Password-Request",
  6507.                                               8: "Password-Ack",
  6508.                                               9: "Password-Reject",
  6509.                                               10: "Accounting-Message",
  6510.                                               11: "Access-Challenge",
  6511.                                               12: "Status-Server",
  6512.                                               13: "Status-Client",
  6513.                                               21: "Resource-Free-Request",
  6514.                                               22: "Resource-Free-Response",
  6515.                                               23: "Resource-Query-Request",
  6516.                                               24: "Resource-Query-Response",
  6517.                                               25: "Alternate-Resource-Reclaim-Request",
  6518.                                               26: "NAS-Reboot-Request",
  6519.                                               27: "NAS-Reboot-Response",
  6520.                                               29: "Next-Passcode",
  6521.                                               30: "New-Pin",
  6522.                                               31: "Terminate-Session",
  6523.                                               32: "Password-Expired",
  6524.                                               33: "Event-Request",
  6525.                                               34: "Event-Response",
  6526.                                               40: "Disconnect-Request",
  6527.                                               41: "Disconnect-ACK",
  6528.                                               42: "Disconnect-NAK",
  6529.                                               43: "CoA-Request",
  6530.                                               44: "CoA-ACK",
  6531.                                               45: "CoA-NAK",
  6532.                                               50: "IP-Address-Allocate",
  6533.                                               51: "IP-Address-Release",
  6534.                                               253: "Experimental-use",
  6535.                                               254: "Reserved",
  6536.                                               255: "Reserved"} ),
  6537.                     ByteField("id", 0),
  6538.                     ShortField("len", None),
  6539.                     StrFixedLenField("authenticator","",16) ]
  6540.     def post_build(self, p):
  6541.         l = self.len
  6542.         if l is None:
  6543.             l = len(p)
  6544.             p = p[:2]+struct.pack("!H",l)+p[4:]
  6545.         return p
  6546.  
  6547.  
  6548.  
  6549.  
  6550. class RIP(Packet):
  6551.     name = "RIP header"
  6552.     fields_desc = [
  6553.         ByteEnumField("command",1,{1:"req",2:"resp",3:"traceOn",4:"traceOff",5:"sun",
  6554.                                    6:"trigReq",7:"trigResp",8:"trigAck",9:"updateReq",
  6555.                                    10:"updateResp",11:"updateAck"}),
  6556.         ByteField("version",1),
  6557.         ShortField("null",0),
  6558.         ]
  6559.  
  6560. class RIPEntry(Packet):
  6561.     name = "RIP entry"
  6562.     fields_desc = [
  6563.         ShortEnumField("AF",2,{2:"IP"}),
  6564.         ShortField("RouteTag",0),
  6565.         IPField("addr","0.0.0.0"),
  6566.         IPField("mask","0.0.0.0"),
  6567.         IPField("nextHop","0.0.0.0"),
  6568.         IntEnumField("metric",1,{16:"Unreach"}),
  6569.         ]
  6570.         
  6571.  
  6572.  
  6573.  
  6574. ISAKMP_payload_type = ["None","SA","Proposal","Transform","KE","ID","CERT","CR","Hash",
  6575.                        "SIG","Nonce","N","D","VendorID"]
  6576.  
  6577. ISAKMP_exchange_type = ["None","base","identity prot.",
  6578.                         "auth only", "aggressive", "info"]
  6579.  
  6580.  
  6581. class ISAKMP_class(Packet):
  6582.     def guess_payload_class(self, payload):
  6583.         np = self.next_payload
  6584.         if np == 0:
  6585.             return Padding
  6586.         elif np < len(ISAKMP_payload_type):
  6587.             pt = ISAKMP_payload_type[np]
  6588.             return globals().get("ISAKMP_payload_%s" % pt, ISAKMP_payload)
  6589.         else:
  6590.             return ISAKMP_payload
  6591.  
  6592.  
  6593. class ISAKMP(ISAKMP_class): # rfc2408
  6594.     name = "ISAKMP"
  6595.     fields_desc = [
  6596.         StrFixedLenField("init_cookie","",8),
  6597.         StrFixedLenField("resp_cookie","",8),
  6598.         ByteEnumField("next_payload",0,ISAKMP_payload_type),
  6599.         XByteField("version",0x10),
  6600.         ByteEnumField("exch_type",0,ISAKMP_exchange_type),
  6601.         ByteField("flags",0), # XXX use a Flag field
  6602.         IntField("id",0),
  6603.         IntField("length",None)
  6604.         ]
  6605.  
  6606.     def answers(self, other):
  6607.         if isinstance(other, ISAKMP):
  6608.             if other.init_cookie == self.init_cookie:
  6609.                 return 1
  6610.         return 0
  6611.     def post_build(self, p):
  6612.         if self.length is None:
  6613.             p = p[:24]+struct.pack("!I",len(p))+p[28:]
  6614.         return p
  6615.        
  6616.  
  6617.  
  6618.  
  6619. class ISAKMP_payload_Transform(ISAKMP_class):
  6620.     name = "IKE Transform"
  6621.     fields_desc = [
  6622.         ByteEnumField("next_payload",None,ISAKMP_payload_type),
  6623.         ByteField("res",0),
  6624. #        ShortField("len",None),
  6625.         FieldLenField("length",None,"transforms","H",shift=-8),
  6626.         ByteField("num",None),
  6627.         ByteEnumField("id",1,{1:"KEY_IKE"}),
  6628.         ShortField("res2",0),
  6629.         ISAKMPTransformSetField("transforms",None,"length")
  6630. #        XIntField("enc",0x80010005L),
  6631. #        XIntField("hash",0x80020002L),
  6632. #        XIntField("auth",0x80030001L),
  6633. #        XIntField("group",0x80040002L),
  6634. #        XIntField("life_type",0x800b0001L),
  6635. #        XIntField("durationh",0x000c0004L),
  6636. #        XIntField("durationl",0x00007080L),
  6637.         ]
  6638.  
  6639.  
  6640.         
  6641. class ISAKMP_payload_Proposal(ISAKMP_class):
  6642.     name = "IKE proposal"
  6643. #    ISAKMP_payload_type = 0
  6644.     fields_desc = [
  6645.         ByteEnumField("next_payload",None,ISAKMP_payload_type),
  6646.         ByteField("res",0),
  6647.         FieldLenField("length",None,"trans","H",shift=-8),
  6648.         ByteField("proposal",1),
  6649.         ByteEnumField("proto",1,{1:"ISAKMP"}),
  6650.         ByteField("SPIsize",0),
  6651.         ByteField("trans_nb",None),
  6652.         PacketLenField("trans",Raw(),ISAKMP_payload_Transform,"length"),
  6653.         ]
  6654.  
  6655.  
  6656. class ISAKMP_payload_metaclass(type):
  6657.     def __new__(cls, name, bases, dct):
  6658.         f = dct["fields_desc"]
  6659.         f = [ ByteEnumField("next_payload",None,ISAKMP_payload_type),
  6660.               ByteField("res",0),
  6661.               ShortField("length",None),
  6662.               ] + f
  6663.         dct["fields_desc"] = f
  6664.         return super(ISAKMP_payload_metaclass, cls).__new__(cls, name, bases, dct)
  6665.  
  6666.  
  6667. class ISAKMP_payload(ISAKMP_class):
  6668.     name = "ISAKMP payload"
  6669.     fields_desc = [
  6670.         ByteEnumField("next_payload",None,ISAKMP_payload_type),
  6671.         ByteField("res",0),
  6672.         FieldLenField("length",None,"load","H",shift=-4),
  6673.         StrLenField("load","","length"),
  6674.         ]
  6675.  
  6676.  
  6677. class ISAKMP_payload_VendorID(ISAKMP_class):
  6678.     name = "ISAKMP Vendor ID"
  6679.     overload_fields = { ISAKMP: { "next_payload":13 }}
  6680.     fields_desc = [
  6681.         ByteEnumField("next_payload",None,ISAKMP_payload_type),
  6682.         ByteField("res",0),
  6683.         FieldLenField("length",None,"vendorID","H",shift=-4),
  6684.         StrLenField("vendorID","","length"),
  6685.         ]
  6686.  
  6687. class ISAKMP_payload_SA(ISAKMP_class):
  6688.     name = "ISAKMP SA"
  6689.     overload_fields = { ISAKMP: { "next_payload":1 }}
  6690.     fields_desc = [
  6691.         ByteEnumField("next_payload",None,ISAKMP_payload_type),
  6692.         ByteField("res",0),
  6693.         FieldLenField("length",None,"prop","H",shift=-12),
  6694.         IntEnumField("DOI",1,{1:"IPSEC"}),
  6695.         IntEnumField("situation",1,{1:"identity"}),
  6696.         PacketLenField("prop",Raw(),ISAKMP_payload_Proposal,"length"),
  6697.         ]
  6698.  
  6699. class ISAKMP_payload_Nonce(ISAKMP_class):
  6700.     name = "ISAKMP Nonce"
  6701.     overload_fields = { ISAKMP: { "next_payload":10 }}
  6702.     fields_desc = [
  6703.         ByteEnumField("next_payload",None,ISAKMP_payload_type),
  6704.         ByteField("res",0),
  6705.         FieldLenField("length",None,"load","H",shift=-4),
  6706.         StrLenField("load","","length"),
  6707.         ]
  6708.  
  6709. class ISAKMP_payload_KE(ISAKMP_class):
  6710.     name = "ISAKMP Key Exchange"
  6711.     overload_fields = { ISAKMP: { "next_payload":4 }}
  6712.     fields_desc = [
  6713.         ByteEnumField("next_payload",None,ISAKMP_payload_type),
  6714.         ByteField("res",0),
  6715.         FieldLenField("length",None,"load","H",shift=-4),
  6716.         StrLenField("load","","length"),
  6717.         ]
  6718.  
  6719. class ISAKMP_payload_ID(ISAKMP_class):
  6720.     name = "ISAKMP Identification"
  6721.     overload_fields = { ISAKMP: { "next_payload":5 }}
  6722.     fields_desc = [
  6723.         ByteEnumField("next_payload",None,ISAKMP_payload_type),
  6724.         ByteField("res",0),
  6725.         FieldLenField("length",None,"load","H",shift=-8),
  6726.         ByteEnumField("IDtype",1,{1:"IPv4_addr", 11:"Key"}),
  6727.         ByteEnumField("ProtoID",0,{0:"Unused"}),
  6728.         ShortEnumField("Port",0,{0:"Unused"}),
  6729. #        IPField("IdentData","127.0.0.1"),
  6730.         StrLenField("load","","length"),
  6731.         ]
  6732.  
  6733.  
  6734.  
  6735. class ISAKMP_payload_Hash(ISAKMP_class):
  6736.     name = "ISAKMP Hash"
  6737.     overload_fields = { ISAKMP: { "next_payload":8 }}
  6738.     fields_desc = [
  6739.         ByteEnumField("next_payload",None,ISAKMP_payload_type),
  6740.         ByteField("res",0),
  6741.         FieldLenField("length",None,"load","H",shift=-4),
  6742.         StrLenField("load","","length"),
  6743.         ]
  6744.  
  6745.  
  6746.  
  6747.  
  6748.         
  6749.  
  6750. # Cisco Skinny protocol
  6751.  
  6752. # shamelessly ripped from Ethereal dissector
  6753. skinny_messages = { 
  6754. # Station -> Callmanager
  6755.   0x0000: "KeepAliveMessage",
  6756.   0x0001: "RegisterMessage",
  6757.   0x0002: "IpPortMessage",
  6758.   0x0003: "KeypadButtonMessage",
  6759.   0x0004: "EnblocCallMessage",
  6760.   0x0005: "StimulusMessage",
  6761.   0x0006: "OffHookMessage",
  6762.   0x0007: "OnHookMessage",
  6763.   0x0008: "HookFlashMessage",
  6764.   0x0009: "ForwardStatReqMessage",
  6765.   0x000A: "SpeedDialStatReqMessage",
  6766.   0x000B: "LineStatReqMessage",
  6767.   0x000C: "ConfigStatReqMessage",
  6768.   0x000D: "TimeDateReqMessage",
  6769.   0x000E: "ButtonTemplateReqMessage",
  6770.   0x000F: "VersionReqMessage",
  6771.   0x0010: "CapabilitiesResMessage",
  6772.   0x0011: "MediaPortListMessage",
  6773.   0x0012: "ServerReqMessage",
  6774.   0x0020: "AlarmMessage",
  6775.   0x0021: "MulticastMediaReceptionAck",
  6776.   0x0022: "OpenReceiveChannelAck",
  6777.   0x0023: "ConnectionStatisticsRes",
  6778.   0x0024: "OffHookWithCgpnMessage",
  6779.   0x0025: "SoftKeySetReqMessage",
  6780.   0x0026: "SoftKeyEventMessage",
  6781.   0x0027: "UnregisterMessage",
  6782.   0x0028: "SoftKeyTemplateReqMessage",
  6783.   0x0029: "RegisterTokenReq",
  6784.   0x002A: "MediaTransmissionFailure",
  6785.   0x002B: "HeadsetStatusMessage",
  6786.   0x002C: "MediaResourceNotification",
  6787.   0x002D: "RegisterAvailableLinesMessage",
  6788.   0x002E: "DeviceToUserDataMessage",
  6789.   0x002F: "DeviceToUserDataResponseMessage",
  6790.   0x0030: "UpdateCapabilitiesMessage",
  6791.   0x0031: "OpenMultiMediaReceiveChannelAckMessage",
  6792.   0x0032: "ClearConferenceMessage",
  6793.   0x0033: "ServiceURLStatReqMessage",
  6794.   0x0034: "FeatureStatReqMessage",
  6795.   0x0035: "CreateConferenceResMessage",
  6796.   0x0036: "DeleteConferenceResMessage",
  6797.   0x0037: "ModifyConferenceResMessage",
  6798.   0x0038: "AddParticipantResMessage",
  6799.   0x0039: "AuditConferenceResMessage",
  6800.   0x0040: "AuditParticipantResMessage",
  6801.   0x0041: "DeviceToUserDataVersion1Message",
  6802. # Callmanager -> Station */
  6803.   0x0081: "RegisterAckMessage",
  6804.   0x0082: "StartToneMessage",
  6805.   0x0083: "StopToneMessage",
  6806.   0x0085: "SetRingerMessage",
  6807.   0x0086: "SetLampMessage",
  6808.   0x0087: "SetHkFDetectMessage",
  6809.   0x0088: "SetSpeakerModeMessage",
  6810.   0x0089: "SetMicroModeMessage",
  6811.   0x008A: "StartMediaTransmission",
  6812.   0x008B: "StopMediaTransmission",
  6813.   0x008C: "StartMediaReception",
  6814.   0x008D: "StopMediaReception",
  6815.   0x008F: "CallInfoMessage",
  6816.   0x0090: "ForwardStatMessage",
  6817.   0x0091: "SpeedDialStatMessage",
  6818.   0x0092: "LineStatMessage",
  6819.   0x0093: "ConfigStatMessage",
  6820.   0x0094: "DefineTimeDate",
  6821.   0x0095: "StartSessionTransmission",
  6822.   0x0096: "StopSessionTransmission",
  6823.   0x0097: "ButtonTemplateMessage",
  6824.   0x0098: "VersionMessage",
  6825.   0x0099: "DisplayTextMessage",
  6826.   0x009A: "ClearDisplay",
  6827.   0x009B: "CapabilitiesReqMessage",
  6828.   0x009C: "EnunciatorCommandMessage",
  6829.   0x009D: "RegisterRejectMessage",
  6830.   0x009E: "ServerResMessage",
  6831.   0x009F: "Reset",
  6832.   0x0100: "KeepAliveAckMessage",
  6833.   0x0101: "StartMulticastMediaReception",
  6834.   0x0102: "StartMulticastMediaTransmission",
  6835.   0x0103: "StopMulticastMediaReception",
  6836.   0x0104: "StopMulticastMediaTransmission",
  6837.   0x0105: "OpenReceiveChannel",
  6838.   0x0106: "CloseReceiveChannel",
  6839.   0x0107: "ConnectionStatisticsReq",
  6840.   0x0108: "SoftKeyTemplateResMessage",
  6841.   0x0109: "SoftKeySetResMessage",
  6842.   0x0110: "SelectSoftKeysMessage",
  6843.   0x0111: "CallStateMessage",
  6844.   0x0112: "DisplayPromptStatusMessage",
  6845.   0x0113: "ClearPromptStatusMessage",
  6846.   0x0114: "DisplayNotifyMessage",
  6847.   0x0115: "ClearNotifyMessage",
  6848.   0x0116: "ActivateCallPlaneMessage",
  6849.   0x0117: "DeactivateCallPlaneMessage",
  6850.   0x0118: "UnregisterAckMessage",
  6851.   0x0119: "BackSpaceReqMessage",
  6852.   0x011A: "RegisterTokenAck",
  6853.   0x011B: "RegisterTokenReject",
  6854.   0x0042: "DeviceToUserDataResponseVersion1Message",
  6855.   0x011C: "StartMediaFailureDetection",
  6856.   0x011D: "DialedNumberMessage",
  6857.   0x011E: "UserToDeviceDataMessage",
  6858.   0x011F: "FeatureStatMessage",
  6859.   0x0120: "DisplayPriNotifyMessage",
  6860.   0x0121: "ClearPriNotifyMessage",
  6861.   0x0122: "StartAnnouncementMessage",
  6862.   0x0123: "StopAnnouncementMessage",
  6863.   0x0124: "AnnouncementFinishMessage",
  6864.   0x0127: "NotifyDtmfToneMessage",
  6865.   0x0128: "SendDtmfToneMessage",
  6866.   0x0129: "SubscribeDtmfPayloadReqMessage",
  6867.   0x012A: "SubscribeDtmfPayloadResMessage",
  6868.   0x012B: "SubscribeDtmfPayloadErrMessage",
  6869.   0x012C: "UnSubscribeDtmfPayloadReqMessage",
  6870.   0x012D: "UnSubscribeDtmfPayloadResMessage",
  6871.   0x012E: "UnSubscribeDtmfPayloadErrMessage",
  6872.   0x012F: "ServiceURLStatMessage",
  6873.   0x0130: "CallSelectStatMessage",
  6874.   0x0131: "OpenMultiMediaChannelMessage",
  6875.   0x0132: "StartMultiMediaTransmission",
  6876.   0x0133: "StopMultiMediaTransmission",
  6877.   0x0134: "MiscellaneousCommandMessage",
  6878.   0x0135: "FlowControlCommandMessage",
  6879.   0x0136: "CloseMultiMediaReceiveChannel",
  6880.   0x0137: "CreateConferenceReqMessage",
  6881.   0x0138: "DeleteConferenceReqMessage",
  6882.   0x0139: "ModifyConferenceReqMessage",
  6883.   0x013A: "AddParticipantReqMessage",
  6884.   0x013B: "DropParticipantReqMessage",
  6885.   0x013C: "AuditConferenceReqMessage",
  6886.   0x013D: "AuditParticipantReqMessage",
  6887.   0x013F: "UserToDeviceDataVersion1Message",
  6888.   }
  6889.  
  6890.  
  6891.         
  6892. class Skinny(Packet):
  6893.     name="Skinny"
  6894.     fields_desc = [ LEIntField("len",0),
  6895.                     LEIntField("res",0),
  6896.                     LEIntEnumField("msg",0,skinny_messages) ]
  6897.     
  6898.  
  6899.  
  6900. ### SEBEK
  6901.  
  6902.  
  6903. class SebekHead(Packet):
  6904.     name = "Sebek header"
  6905.     fields_desc = [ XIntField("magic", 0xd0d0d0),
  6906.                     ShortField("version", 1),
  6907.                     ShortEnumField("type", 0, {"read":0, "write":1,
  6908.                                              "socket":2, "open":3}),
  6909.                     IntField("counter", 0),
  6910.                     IntField("time_sec", 0),
  6911.                     IntField("time_usec", 0) ]
  6912.     def mysummary(self):
  6913.         return self.sprintf("Sebek Header v%SebekHead.version% %SebekHead.type%")
  6914.  
  6915. # we need this because Sebek headers differ between v1 and v3, and
  6916. # between v3 type socket and v3 others
  6917.  
  6918. class SebekV1(Packet):
  6919.     name = "Sebek v1"
  6920.     fields_desc = [ IntField("pid", 0),
  6921.                     IntField("uid", 0),
  6922.                     IntField("fd", 0),
  6923.                     StrFixedLenField("command", "", 12),
  6924.                     FieldLenField("data_length", None, "data",fmt="I"),
  6925.                     StrLenField("data", "", "data_length") ]
  6926.     def mysummary(self):
  6927.         if isinstance(self.underlayer, SebekHead):
  6928.             return self.underlayer.sprintf("Sebek v1 %SebekHead.type% (%SebekV1.command%)")
  6929.         else:
  6930.             return self.sprintf("Sebek v1 (%SebekV1.command%)")
  6931.  
  6932. class SebekV3(Packet):
  6933.     name = "Sebek v3"
  6934.     fields_desc = [ IntField("parent_pid", 0),
  6935.                     IntField("pid", 0),
  6936.                     IntField("uid", 0),
  6937.                     IntField("fd", 0),
  6938.                     IntField("inode", 0),
  6939.                     StrFixedLenField("command", "", 12),
  6940.                     FieldLenField("data_length", None, "data",fmt="I"),
  6941.                     StrLenField("data", "", "data_length") ]
  6942.     def mysummary(self):
  6943.         if isinstance(self.underlayer, SebekHead):
  6944.             return self.underlayer.sprintf("Sebek v%SebekHead.version% %SebekHead.type% (%SebekV3.command%)")
  6945.         else:
  6946.             return self.sprintf("Sebek v3 (%SebekV3.command%)")
  6947.  
  6948. class SebekV2(SebekV3):
  6949.     def mysummary(self):
  6950.         if isinstance(self.underlayer, SebekHead):
  6951.             return self.underlayer.sprintf("Sebek v%SebekHead.version% %SebekHead.type% (%SebekV2.command%)")
  6952.         else:
  6953.             return self.sprintf("Sebek v2 (%SebekV2.command%)")
  6954.  
  6955. class SebekV3Sock(Packet):
  6956.     name = "Sebek v2 socket"
  6957.     fields_desc = [ IntField("parent_pid", 0),
  6958.                     IntField("pid", 0),
  6959.                     IntField("uid", 0),
  6960.                     IntField("fd", 0),
  6961.                     IntField("inode", 0),
  6962.                     StrFixedLenField("command", "", 12),
  6963.                     IntField("data_length", 15),
  6964.                     IPField("dip", "127.0.0.1"),
  6965.                     ShortField("dport", 0),
  6966.                     IPField("sip", "127.0.0.1"),
  6967.                     ShortField("sport", 0),
  6968.                     ShortEnumField("call", 0, { "bind":2,
  6969.                                                 "connect":3, "listen":4,
  6970.                                                "accept":5, "sendmsg":16,
  6971.                                                "recvmsg":17, "sendto":11,
  6972.                                                "recvfrom":12}),
  6973.                     ByteEnumField("proto", 0, IP_PROTOS) ]
  6974.     def mysummary(self):
  6975.         if isinstance(self.underlayer, SebekHead):
  6976.             return self.underlayer.sprintf("Sebek v%SebekHead.version% %SebekHead.type% (%SebekV3Sock.command%)")
  6977.         else:
  6978.             return self.sprintf("Sebek v3 socket (%SebekV3Sock.command%)")
  6979.  
  6980. class SebekV2Sock(SebekV3Sock):
  6981.     def mysummary(self):
  6982.         if isinstance(self.underlayer, SebekHead):
  6983.             return self.underlayer.sprintf("Sebek v%SebekHead.version% %SebekHead.type% (%SebekV2Sock.command%)")
  6984.         else:
  6985.             return self.sprintf("Sebek v2 socket (%SebekV2Sock.command%)")
  6986.  
  6987. class MGCP(Packet):
  6988.     name = "MGCP"
  6989.     longname = "Media Gateway Control Protocol"
  6990.     fields_desc = [ StrStopField("verb","AUEP"," ", -1),
  6991.                     StrFixedLenField("sep1"," ",1),
  6992.                     StrStopField("transaction_id","1234567"," ", -1),
  6993.                     StrFixedLenField("sep2"," ",1),
  6994.                     StrStopField("endpoint","dummy@dummy.net"," ", -1),
  6995.                     StrFixedLenField("sep3"," ",1),
  6996.                     StrStopField("version","MGCP 1.0 NCS 1.0","\x0a", -1),
  6997.                     StrFixedLenField("sep4","\x0a",1),
  6998.                     ]
  6999.                     
  7000.     
  7001. #class MGCP(Packet):
  7002. #    name = "MGCP"
  7003. #    longname = "Media Gateway Control Protocol"
  7004. #    fields_desc = [ ByteEnumField("type",0, ["request","response","others"]),
  7005. #                    ByteField("code0",0),
  7006. #                    ByteField("code1",0),
  7007. #                    ByteField("code2",0),
  7008. #                    ByteField("code3",0),
  7009. #                    ByteField("code4",0),
  7010. #                    IntField("trasid",0),
  7011. #                    IntField("req_time",0),
  7012. #                    ByteField("is_duplicate",0),
  7013. #                    ByteField("req_available",0) ]
  7014. #
  7015. class GPRS(Packet):
  7016.     name = "GPRSdummy"
  7017.     fields_desc = [
  7018.         StrStopField("dummy","","\x65\x00\x00",1)
  7019.         ]
  7020.  
  7021.  
  7022. class HCI_Hdr(Packet):
  7023.     name = "HCI header"
  7024.     fields_desc = [ ByteEnumField("type",2,{1:"command",2:"ACLdata",3:"SCOdata",4:"event",5:"vendor"}),]
  7025.  
  7026.     def mysummary(self):
  7027.         return self.sprintf("HCI %type%")
  7028.  
  7029. class HCI_ACL_Hdr(Packet):
  7030.     name = "HCI ACL header"
  7031.     fields_desc = [ ByteField("handle",0), # Actually, handle is 12 bits and flags is 4.
  7032.                     ByteField("flags",0),  # I wait to write a LEBitField
  7033.                     LEShortField("len",None), ]
  7034.     def post_build(self, p):
  7035.         if self.len is None:
  7036.             l = len(p)-4
  7037.             p = p[:2]+chr(l&0xff)+chr((l>>8)&0xff)+p[4:]
  7038.         return p
  7039.                     
  7040.  
  7041. class L2CAP_Hdr(Packet):
  7042.     name = "L2CAP header"
  7043.     fields_desc = [ LEShortField("len",None),
  7044.                     LEShortEnumField("cid",0,{1:"control"}),]
  7045.     
  7046.     def post_build(self, p):
  7047.         if self.len is None:
  7048.             l = len(p)-4
  7049.             p = p[:2]+chr(l&0xff)+chr((l>>8)&0xff)+p[4:]
  7050.         return p
  7051.                     
  7052.                 
  7053.  
  7054. class L2CAP_CmdHdr(Packet):
  7055.     name = "L2CAP command header"
  7056.     fields_desc = [
  7057.         ByteEnumField("code",8,{1:"rej",2:"conn_req",3:"conn_resp",
  7058.                                 4:"conf_req",5:"conf_resp",6:"disconn_req",
  7059.                                 7:"disconn_resp",8:"echo_req",9:"echo_resp",
  7060.                                 10:"info_req",11:"info_resp"}),
  7061.         ByteField("id",0),
  7062.         LEShortField("len",None) ]
  7063.     def post_build(self, p):
  7064.         if self.len is None:
  7065.             l = len(p)-4
  7066.             p = p[:2]+chr(l&0xff)+chr((l>>8)&0xff)+p[4:]
  7067.         return p
  7068.     def answers(self, other):
  7069.         if other.id == self.id:
  7070.             if self.code == 1:
  7071.                 return 1
  7072.             if other.code in [2,4,6,8,10] and self.code == other.code+1:
  7073.                 if other.code == 8:
  7074.                     return 1
  7075.                 return self.payload.answers(other.payload)
  7076.         return 0
  7077.  
  7078. class L2CAP_ConnReq(Packet):
  7079.     name = "L2CAP Conn Req"
  7080.     fields_desc = [ LEShortEnumField("psm",0,{1:"SDP",3:"RFCOMM",5:"telephony control"}),
  7081.                     LEShortField("scid",0),
  7082.                     ]
  7083.  
  7084. class L2CAP_ConnResp(Packet):
  7085.     name = "L2CAP Conn Resp"
  7086.     fields_desc = [ LEShortField("dcid",0),
  7087.                     LEShortField("scid",0),
  7088.                     LEShortEnumField("result",0,["no_info","authen_pend","author_pend"]),
  7089.                     LEShortEnumField("status",0,["success","pend","bad_psm",
  7090.                                                "cr_sec_block","cr_no_mem"]),
  7091.                     ]
  7092.     def answers(self, other):
  7093.         return self.scid == other.scid
  7094.  
  7095. class L2CAP_CmdRej(Packet):
  7096.     name = "L2CAP Command Rej"
  7097.     fields_desc = [ LEShortField("reason",0),
  7098.                     ]
  7099.     
  7100.  
  7101. class L2CAP_ConfReq(Packet):
  7102.     name = "L2CAP Conf Req"
  7103.     fields_desc = [ LEShortField("dcid",0),
  7104.                     LEShortField("flags",0),
  7105.                     ]
  7106.  
  7107. class L2CAP_ConfResp(Packet):
  7108.     name = "L2CAP Conf Resp"
  7109.     fields_desc = [ LEShortField("scid",0),
  7110.                     LEShortField("flags",0),
  7111.                     LEShortEnumField("result",0,["success","unaccept","reject","unknown"]),
  7112.                     ]
  7113.     def answers(self, other):
  7114.         return self.scid == other.scid
  7115.  
  7116.  
  7117. class L2CAP_DisconnReq(Packet):
  7118.     name = "L2CAP Disconn Req"
  7119.     fields_desc = [ LEShortField("dcid",0),
  7120.                     LEShortField("scid",0), ]
  7121.  
  7122. class L2CAP_DisconnResp(Packet):
  7123.     name = "L2CAP Disconn Resp"
  7124.     fields_desc = [ LEShortField("dcid",0),
  7125.                     LEShortField("scid",0), ]
  7126.     def answers(self, other):
  7127.         return self.scid == other.scid
  7128.  
  7129.     
  7130.  
  7131. class L2CAP_InfoReq(Packet):
  7132.     name = "L2CAP Info Req"
  7133.     fields_desc = [ LEShortEnumField("type",0,{1:"CL_MTU",2:"FEAT_MASK"}),
  7134.                     StrField("data","")
  7135.                     ]
  7136.  
  7137.  
  7138. class L2CAP_InfoResp(Packet):
  7139.     name = "L2CAP Info Resp"
  7140.     fields_desc = [ LEShortField("type",0),
  7141.                     LEShortEnumField("result",0,["success","not_supp"]),
  7142.                     StrField("data",""), ]
  7143.     def answers(self, other):
  7144.         return self.type == other.type
  7145.  
  7146.  
  7147.  
  7148.  
  7149. class NetBIOS_DS(Packet):
  7150.     name = "NetBIOS datagram service"
  7151.     fields_desc = [
  7152.         ByteEnumField("type",17, {17:"direct_group"}),
  7153.         ByteField("flags",0),
  7154.         XShortField("id",0),
  7155.         IPField("src","127.0.0.1"),
  7156.         ShortField("sport",138),
  7157.         ShortField("len",None),
  7158.         ShortField("ofs",0),
  7159.         NetBIOSNameField("srcname",""),
  7160.         NetBIOSNameField("dstname",""),
  7161.         ]
  7162.     def post_build(self, p):
  7163.         if self.len is None:
  7164.             l = len(p)-14
  7165.             p = p[:10]+struct.pack("!H", l)+p[12:]
  7166.         return p
  7167.         
  7168. #        ShortField("length",0),
  7169. #        ShortField("Delimitor",0),
  7170. #        ByteField("command",0),
  7171. #        ByteField("data1",0),
  7172. #        ShortField("data2",0),
  7173. #        ShortField("XMIt",0),
  7174. #        ShortField("RSPCor",0),
  7175. #        StrFixedLenField("dest","",16),
  7176. #        StrFixedLenField("source","",16),
  7177. #        
  7178. #        ]
  7179. #
  7180.  
  7181. # IR
  7182.  
  7183. class IrLAPHead(Packet):
  7184.     name = "IrDA Link Access Protocol Header"
  7185.     fields_desc = [ XBitField("Address", 0x7f, 7),
  7186.                     BitEnumField("Type", 1, 1, {"Response":0,
  7187.                                                 "Command":1})]
  7188.  
  7189. class IrLAPCommand(Packet):
  7190.     name = "IrDA Link Access Protocol Command"
  7191.     fields_desc = [ XByteField("Control", 0),
  7192.                     XByteField("Format identifier", 0),
  7193.                     XIntField("Source address", 0),
  7194.                     XIntField("Destination address", 0xffffffffL),
  7195.                     XByteField("Discovery flags", 0x1),
  7196.                     ByteEnumField("Slot number", 255, {"final":255}),
  7197.                     XByteField("Version", 0)]
  7198.  
  7199.  
  7200. class IrLMP(Packet):
  7201.     name = "IrDA Link Management Protocol"
  7202.     fields_desc = [ XShortField("Service hints", 0),
  7203.                     XByteField("Character set", 0),
  7204.                     StrField("Device name", "") ]
  7205.  
  7206.  
  7207. #NetBIOS
  7208.  
  7209.  
  7210. # Name Query Request
  7211. # Node Status Request
  7212. class NBNSQueryRequest(Packet):
  7213.     name="NBNS query request"
  7214.     fields_desc = [ShortField("NAME_TRN_ID",0),
  7215.                    ShortField("FLAGS", 0x0110),
  7216.                    ShortField("QDCOUNT",1),
  7217.                    ShortField("ANCOUNT",0),
  7218.                    ShortField("NSCOUNT",0),
  7219.                    ShortField("ARCOUNT",0),
  7220.                    NetBIOSNameField("QUESTION_NAME","windows"),
  7221.                    ShortEnumField("SUFFIX",0x4141,{0x4141:"workstation",0x4141+0x03:"messenger service",0x4141+0x200:"file server service",0x4141+0x10b:"domain master browser",0x4141+0x10c:"domain controller", 0x4141+0x10e:"browser election service"}),
  7222.                    ByteField("NULL",0),
  7223.                    ShortEnumField("QUESTION_TYPE",0x20, {0x20:"NB",0x21:"NBSTAT"}),
  7224.                    ShortEnumField("QUESTION_CLASS",1,{1:"INTERNET"})]
  7225.  
  7226. # Name Registration Request
  7227. # Name Refresh Request
  7228. # Name Release Request or Demand
  7229. class NBNSRequest(Packet):
  7230.     name="NBNS request"
  7231.     fields_desc = [ShortField("NAME_TRN_ID",0),
  7232.                    ShortField("FLAGS", 0x2910),
  7233.                    ShortField("QDCOUNT",1),
  7234.                    ShortField("ANCOUNT",0),
  7235.                    ShortField("NSCOUNT",0),
  7236.                    ShortField("ARCOUNT",1),
  7237.                    NetBIOSNameField("QUESTION_NAME","windows"),
  7238.                    ShortEnumField("SUFFIX",0x4141,{0x4141:"workstation",0x4141+0x03:"messenger service",0x4141+0x200:"file server service",0x4141+0x10b:"domain master browser",0x4141+0x10c:"domain controller", 0x4141+0x10e:"browser election service"}),
  7239.                    ByteField("NULL",0),
  7240.                    ShortEnumField("QUESTION_TYPE",0x20, {0x20:"NB",0x21:"NBSTAT"}),
  7241.                    ShortEnumField("QUESTION_CLASS",1,{1:"INTERNET"}),
  7242.                    ShortEnumField("RR_NAME",0xC00C,{0xC00C:"Label String Pointer to QUESTION_NAME"}),
  7243.                    ShortEnumField("RR_TYPE",0x20, {0x20:"NB",0x21:"NBSTAT"}),
  7244.                    ShortEnumField("RR_CLASS",1,{1:"INTERNET"}),
  7245.                    IntField("TTL", 0),
  7246.                    ShortField("RDLENGTH", 6),
  7247.                    BitEnumField("G",0,1,{0:"Unique name",1:"Group name"}),
  7248.                    BitEnumField("OWNER NODE TYPE",00,2,{00:"B node",01:"P node",02:"M node",03:"H node"}),
  7249.                    BitEnumField("UNUSED",0,13,{0:"Unused"}),
  7250.                    IPField("NB_ADDRESS", "127.0.0.1")]
  7251.  
  7252. # Name Query Response
  7253. # Name Registration Response
  7254. class NBNSQueryResponse(Packet):
  7255.     name="NBNS query response"
  7256.     fields_desc = [ShortField("NAME_TRN_ID",0),
  7257.                    ShortField("FLAGS", 0x8500),
  7258.                    ShortField("QDCOUNT",0),
  7259.                    ShortField("ANCOUNT",1),
  7260.                    ShortField("NSCOUNT",0),
  7261.                    ShortField("ARCOUNT",0),
  7262.                    NetBIOSNameField("RR_NAME","windows"),
  7263.                    ShortEnumField("SUFFIX",0x4141,{0x4141:"workstation",0x4141+0x03:"messenger service",0x4141+0x200:"file server service",0x4141+0x10b:"domain master browser",0x4141+0x10c:"domain controller", 0x4141+0x10e:"browser election service"}),
  7264.                    ByteField("NULL",0),
  7265.                    ShortEnumField("QUESTION_TYPE",0x20, {0x20:"NB",0x21:"NBSTAT"}),
  7266.                    ShortEnumField("QUESTION_CLASS",1,{1:"INTERNET"}),
  7267.                    IntField("TTL", 0x493e0),
  7268.                    ShortField("RDLENGTH", 6),
  7269.                    ShortField("NB_FLAGS", 0),
  7270.                    IPField("NB_ADDRESS", "127.0.0.1")]
  7271.  
  7272. # Name Query Response (negative)
  7273. # Name Release Response
  7274. class NBNSQueryResponseNegative(Packet):
  7275.     name="NBNS query response (negative)"
  7276.     fields_desc = [ShortField("NAME_TRN_ID",0), 
  7277.                    ShortField("FLAGS", 0x8506),
  7278.                    ShortField("QDCOUNT",0),
  7279.                    ShortField("ANCOUNT",1),
  7280.                    ShortField("NSCOUNT",0),
  7281.                    ShortField("ARCOUNT",0),
  7282.                    NetBIOSNameField("RR_NAME","windows"),
  7283.                    ShortEnumField("SUFFIX",0x4141,{0x4141:"workstation",0x4141+0x03:"messenger service",0x4141+0x200:"file server service",0x4141+0x10b:"domain master browser",0x4141+0x10c:"domain controller", 0x4141+0x10e:"browser election service"}),
  7284.                    ByteField("NULL",0),
  7285.                    ShortEnumField("RR_TYPE",0x20, {0x20:"NB",0x21:"NBSTAT"}),
  7286.                    ShortEnumField("RR_CLASS",1,{1:"INTERNET"}),
  7287.                    IntField("TTL",0),
  7288.                    ShortField("RDLENGTH",6),
  7289.                    BitEnumField("G",0,1,{0:"Unique name",1:"Group name"}),
  7290.                    BitEnumField("OWNER NODE TYPE",00,2,{00:"B node",01:"P node",02:"M node",03:"H node"}),
  7291.                    BitEnumField("UNUSED",0,13,{0:"Unused"}),
  7292.                    IPField("NB_ADDRESS", "127.0.0.1")]
  7293.     
  7294. # Node Status Response
  7295. class NBNSNodeStatusResponse(Packet):
  7296.     name="NBNS Node Status Response"
  7297.     fields_desc = [ShortField("NAME_TRN_ID",0), 
  7298.                    ShortField("FLAGS", 0x8500),
  7299.                    ShortField("QDCOUNT",0),
  7300.                    ShortField("ANCOUNT",1),
  7301.                    ShortField("NSCOUNT",0),
  7302.                    ShortField("ARCOUNT",0),
  7303.                    NetBIOSNameField("RR_NAME","windows"),
  7304.                    ShortEnumField("SUFFIX",0x4141,{0x4141:"workstation",0x4141+0x03:"messenger service",0x4141+0x200:"file server service",0x4141+0x10b:"domain master browser",0x4141+0x10c:"domain controller", 0x4141+0x10e:"browser election service"}),
  7305.                    ByteField("NULL",0),         
  7306.                    ShortEnumField("RR_TYPE",0x21, {0x20:"NB",0x21:"NBSTAT"}),
  7307.                    ShortEnumField("RR_CLASS",1,{1:"INTERNET"}),
  7308.                    IntField("TTL",0),
  7309.                    ShortField("RDLENGTH",83),
  7310.                    ByteField("NUM_NAMES",1)]
  7311.  
  7312. # Service for Node Status Response
  7313. class NBNSNodeStatusResponseService(Packet):
  7314.     name="NBNS Node Status Response Service"
  7315.     fields_desc = [StrFixedLenField("NETBIOS_NAME","WINDOWS         ",15),
  7316.                    ByteEnumField("SUFFIX",0,{0:"workstation",0x03:"messenger service",0x20:"file server service",0x1b:"domain master browser",0x1c:"domain controller", 0x1e:"browser election service"}),
  7317.                    ByteField("NAME_FLAGS",0x4),
  7318.                    ByteEnumField("UNUSED",0,{0:"unused"})]
  7319.  
  7320. # End of Node Status Response packet
  7321. class NBNSNodeStatusResponseEnd(Packet):
  7322.     name="NBNS Node Status Response"
  7323.     fields_desc = [SourceMACField("MAC_ADDRESS"),
  7324.                    BitField("STATISTICS",0,57*8)]
  7325.  
  7326. # Wait for Acknowledgement Response
  7327. class NBNSWackResponse(Packet):
  7328.     name="NBNS Wait for Acknowledgement Response"
  7329.     fields_desc = [ShortField("NAME_TRN_ID",0),
  7330.                    ShortField("FLAGS", 0xBC07),
  7331.                    ShortField("QDCOUNT",0),
  7332.                    ShortField("ANCOUNT",1),
  7333.                    ShortField("NSCOUNT",0),
  7334.                    ShortField("ARCOUNT",0),
  7335.                    NetBIOSNameField("RR_NAME","windows"),
  7336.                    ShortEnumField("SUFFIX",0x4141,{0x4141:"workstation",0x4141+0x03:"messenger service",0x4141+0x200:"file server service",0x4141+0x10b:"domain master browser",0x4141+0x10c:"domain controller", 0x4141+0x10e:"browser election service"}),
  7337.                    ByteField("NULL",0),
  7338.                    ShortEnumField("RR_TYPE",0x20, {0x20:"NB",0x21:"NBSTAT"}),
  7339.                    ShortEnumField("RR_CLASS",1,{1:"INTERNET"}),
  7340.                    IntField("TTL", 2),
  7341.                    ShortField("RDLENGTH",2),
  7342.                    BitField("RDATA",10512,16)] #10512=0010100100010000
  7343.  
  7344. class NBTDatagram(Packet):
  7345.     name="NBT Datagram Packet"
  7346.     fields_desc= [ByteField("Type", 0x10),
  7347.                   ByteField("Flags", 0x02),
  7348.                   ShortField("ID", 0),
  7349.                   IPField("SourceIP", "127.0.0.1"),
  7350.                   ShortField("SourcePort", 138),
  7351.                   ShortField("Length", 272),
  7352.                   ShortField("Offset", 0),
  7353.                   NetBIOSNameField("SourceName","windows"),
  7354.                   ShortEnumField("SUFFIX1",0x4141,{0x4141:"workstation",0x4141+0x03:"messenger service",0x4141+0x200:"file server service",0x4141+0x10b:"domain master browser",0x4141+0x10c:"domain controller", 0x4141+0x10e:"browser election service"}),
  7355.                   ByteField("NULL",0),
  7356.                   NetBIOSNameField("DestinationName","windows"),
  7357.                   ShortEnumField("SUFFIX2",0x4141,{0x4141:"workstation",0x4141+0x03:"messenger service",0x4141+0x200:"file server service",0x4141+0x10b:"domain master browser",0x4141+0x10c:"domain controller", 0x4141+0x10e:"browser election service"}),
  7358.                   ByteField("NULL",0)]
  7359.     
  7360.  
  7361. class NBTSession(Packet):
  7362.     name="NBT Session Packet"
  7363.     fields_desc= [ByteEnumField("TYPE",0,{0x00:"Session Message",0x81:"Session Request",0x82:"Positive Session Response",0x83:"Negative Session Response",0x84:"Retarget Session Response",0x85:"Session Keepalive"}),
  7364.                   BitField("RESERVED",0x00,7),
  7365.                   BitField("LENGTH",0,17)]
  7366.  
  7367.  
  7368. # SMB NetLogon Response Header
  7369. class SMBNetlogon_Protocol_Response_Header(Packet):
  7370.     name="SMBNetlogon Protocol Response Header"
  7371.     fields_desc = [StrFixedLenField("Start","\xffSMB",4),
  7372.                    ByteEnumField("Command",0x25,{0x25:"Trans"}),
  7373.                    ByteField("Error_Class",0x02),
  7374.                    ByteField("Reserved",0),
  7375.                    LEShortField("Error_code",4),
  7376.                    ByteField("Flags",0),
  7377.                    LEShortField("Flags2",0x0000),
  7378.                    LEShortField("PIDHigh",0x0000),
  7379.                    LELongField("Signature",0x0),
  7380.                    LEShortField("Unused",0x0),
  7381.                    LEShortField("TID",0),
  7382.                    LEShortField("PID",0),
  7383.                    LEShortField("UID",0),
  7384.                    LEShortField("MID",0),
  7385.                    ByteField("WordCount",17),
  7386.                    LEShortField("TotalParamCount",0),
  7387.                    LEShortField("TotalDataCount",112),
  7388.                    LEShortField("MaxParamCount",0),
  7389.                    LEShortField("MaxDataCount",0),
  7390.                    ByteField("MaxSetupCount",0),
  7391.                    ByteField("unused2",0),
  7392.                    LEShortField("Flags3",0),
  7393.                    ByteField("TimeOut1",0xe8),
  7394.                    ByteField("TimeOut2",0x03),
  7395.                    LEShortField("unused3",0),
  7396.                    LEShortField("unused4",0),
  7397.                    LEShortField("ParamCount2",0),
  7398.                    LEShortField("ParamOffset",0),
  7399.                    LEShortField("DataCount",112),
  7400.                    LEShortField("DataOffset",92),
  7401.                    ByteField("SetupCount", 3),
  7402.                    ByteField("unused5", 0)]
  7403.  
  7404. # SMB MailSlot Protocol
  7405. class SMBMailSlot(Packet):
  7406.     name = "SMB Mail Slot Protocol"
  7407.     fields_desc = [LEShortField("opcode", 1),
  7408.                    LEShortField("priority", 1),
  7409.                    LEShortField("class", 2),
  7410.                    LEShortField("size", 135),
  7411.                    StrNullField("name","\MAILSLOT\NET\GETDC660")]
  7412.  
  7413. # SMB NetLogon Protocol Response Tail SAM
  7414. class SMBNetlogon_Protocol_Response_Tail_SAM(Packet):
  7415.     name = "SMB Netlogon Protocol Response Tail SAM"
  7416.     fields_desc = [ByteEnumField("Command", 0x17, {0x12:"SAM logon request", 0x17:"SAM Active directory Response"}),
  7417.                    ByteField("unused", 0),
  7418.                    ShortField("Data1", 0),
  7419.                    ShortField("Data2", 0xfd01),
  7420.                    ShortField("Data3", 0),
  7421.                    ShortField("Data4", 0xacde),
  7422.                    ShortField("Data5", 0x0fe5),
  7423.                    ShortField("Data6", 0xd10a),
  7424.                    ShortField("Data7", 0x374c),
  7425.                    ShortField("Data8", 0x83e2),
  7426.                    ShortField("Data9", 0x7dd9),
  7427.                    ShortField("Data10", 0x3a16),
  7428.                    ShortField("Data11", 0x73ff),
  7429.                    ByteField("Data12", 0x04),
  7430.                    StrFixedLenField("Data13", "rmff", 4),
  7431.                    ByteField("Data14", 0x0),
  7432.                    ShortField("Data16", 0xc018),
  7433.                    ByteField("Data18", 0x0a),
  7434.                    StrFixedLenField("Data20", "rmff-win2k", 10),
  7435.                    ByteField("Data21", 0xc0),
  7436.                    ShortField("Data22", 0x18c0),
  7437.                    ShortField("Data23", 0x180a),
  7438.                    StrFixedLenField("Data24", "RMFF-WIN2K", 10),
  7439.                    ShortField("Data25", 0),
  7440.                    ByteField("Data26", 0x17),
  7441.                    StrFixedLenField("Data27", "Default-First-Site-Name", 23),
  7442.                    ShortField("Data28", 0x00c0),
  7443.                    ShortField("Data29", 0x3c10),
  7444.                    ShortField("Data30", 0x00c0),
  7445.                    ShortField("Data31", 0x0200),
  7446.                    ShortField("Data32", 0x0),
  7447.                    ShortField("Data33", 0xac14),
  7448.                    ShortField("Data34", 0x0064),
  7449.                    ShortField("Data35", 0x0),
  7450.                    ShortField("Data36", 0x0),
  7451.                    ShortField("Data37", 0x0),
  7452.                    ShortField("Data38", 0x0),
  7453.                    ShortField("Data39", 0x0d00),
  7454.                    ShortField("Data40", 0x0),
  7455.                    ShortField("Data41", 0xffff)]                   
  7456.  
  7457. # SMB NetLogon Protocol Response Tail LM2.0
  7458. class SMBNetlogon_Protocol_Response_Tail_LM20(Packet):
  7459.     name = "SMB Netlogon Protocol Response Tail LM20"
  7460.     fields_desc = [ByteEnumField("Command",0x06,{0x06:"LM 2.0 Response to logon request"}),
  7461.                    ByteField("unused", 0),
  7462.                    StrFixedLenField("DblSlash", "\\\\", 2),
  7463.                    StrNullField("ServerName","WIN"),
  7464.                    LEShortField("LM20Token", 0xffff)]
  7465.  
  7466. # SMBNegociate Protocol Request Header
  7467. class SMBNegociate_Protocol_Request_Header(Packet):
  7468.     name="SMBNegociate Protocol Request Header"
  7469.     fields_desc = [StrFixedLenField("Start","\xffSMB",4),
  7470.                    ByteEnumField("Command",0x72,{0x72:"SMB_COM_NEGOTIATE"}),
  7471.                    ByteField("Error_Class",0),
  7472.                    ByteField("Reserved",0),
  7473.                    LEShortField("Error_code",0),
  7474.                    ByteField("Flags",0x18),
  7475.                    LEShortField("Flags2",0x0000),
  7476.                    LEShortField("PIDHigh",0x0000),
  7477.                    LELongField("Signature",0x0),
  7478.                    LEShortField("Unused",0x0),
  7479.                    LEShortField("TID",0),
  7480.                    LEShortField("PID",1),
  7481.                    LEShortField("UID",0),
  7482.                    LEShortField("MID",2),
  7483.                    ByteField("WordCount",0),
  7484.                    LEShortField("ByteCount",12)]
  7485.  
  7486. # SMB Negociate Protocol Request Tail
  7487. class SMBNegociate_Protocol_Request_Tail(Packet):
  7488.     name="SMB Negociate Protocol Request Tail"
  7489.     fields_desc=[ByteField("BufferFormat",0x02),
  7490.                  StrNullField("BufferData","NT LM 0.12")]
  7491.  
  7492. # SMBNegociate Protocol Response Advanced Security
  7493. class SMBNegociate_Protocol_Response_Advanced_Security(Packet):
  7494.     name="SMBNegociate Protocol Response Advanced Security"
  7495.     fields_desc = [StrFixedLenField("Start","\xffSMB",4),
  7496.                    ByteEnumField("Command",0x72,{0x72:"SMB_COM_NEGOTIATE"}),
  7497.                    ByteField("Error_Class",0),
  7498.                    ByteField("Reserved",0),
  7499.                    LEShortField("Error_Code",0),
  7500.                    ByteField("Flags",0x98),
  7501.                    LEShortField("Flags2",0x0000),
  7502.                    LEShortField("PIDHigh",0x0000),
  7503.                    LELongField("Signature",0x0),
  7504.                    LEShortField("Unused",0x0),
  7505.                    LEShortField("TID",0),
  7506.                    LEShortField("PID",1),
  7507.                    LEShortField("UID",0),
  7508.                    LEShortField("MID",2),
  7509.                    ByteField("WordCount",17),
  7510.                    LEShortField("DialectIndex",7),
  7511.                    ByteField("SecurityMode",0x03),
  7512.                    LEShortField("MaxMpxCount",50),
  7513.                    LEShortField("MaxNumberVC",1),
  7514.                    LEIntField("MaxBufferSize",16144),
  7515.                    LEIntField("MaxRawSize",65536),
  7516.                    LEIntField("SessionKey",0x0000),
  7517.                    LEShortField("ServerCapabilities",0xf3f9),
  7518.                    BitField("UnixExtensions",0,1),
  7519.                    BitField("Reserved2",0,7),
  7520.                    BitField("ExtendedSecurity",1,1),
  7521.                    BitField("CompBulk",0,2),
  7522.                    BitField("Reserved3",0,5),
  7523. # There have been 127490112000000000 tenths of micro-seconds between 1st january 1601 and 1st january 2005. 127490112000000000=0x1C4EF94D6228000, so ServerTimeHigh=0xD6228000 and ServerTimeLow=0x1C4EF94.
  7524.                    LEIntField("ServerTimeHigh",0xD6228000L),
  7525.                    LEIntField("ServerTimeLow",0x1C4EF94),
  7526.                    LEShortField("ServerTimeZone",0x3c),
  7527.                    ByteField("EncryptionKeyLength",0),
  7528.                    LEFieldLenField("ByteCount", None, "SecurityBlob",shift=16),
  7529.                    BitField("GUID",0,128),
  7530.                    StrLenField("SecurityBlob", "", "ByteCount")]
  7531.  
  7532. # SMBNegociate Protocol Response No Security
  7533. # When using no security, with EncryptionKeyLength=8, you must have an EncryptionKey before the DomainName
  7534. class SMBNegociate_Protocol_Response_No_Security(Packet):
  7535.     name="SMBNegociate Protocol Response No Security"
  7536.     fields_desc = [StrFixedLenField("Start","\xffSMB",4),
  7537.                    ByteEnumField("Command",0x72,{0x72:"SMB_COM_NEGOTIATE"}),
  7538.                    ByteField("Error_Class",0),
  7539.                    ByteField("Reserved",0),
  7540.                    LEShortField("Error_Code",0),
  7541.                    ByteField("Flags",0x98),
  7542.                    LEShortField("Flags2",0x0000),
  7543.                    LEShortField("PIDHigh",0x0000),
  7544.                    LELongField("Signature",0x0),
  7545.                    LEShortField("Unused",0x0),
  7546.                    LEShortField("TID",0),
  7547.                    LEShortField("PID",1),
  7548.                    LEShortField("UID",0),
  7549.                    LEShortField("MID",2),
  7550.                    ByteField("WordCount",17),
  7551.                    LEShortField("DialectIndex",7),
  7552.                    ByteField("SecurityMode",0x03),
  7553.                    LEShortField("MaxMpxCount",50),
  7554.                    LEShortField("MaxNumberVC",1),
  7555.                    LEIntField("MaxBufferSize",16144),
  7556.                    LEIntField("MaxRawSize",65536),
  7557.                    LEIntField("SessionKey",0x0000),
  7558.                    LEShortField("ServerCapabilities",0xf3f9),
  7559.                    BitField("UnixExtensions",0,1),
  7560.                    BitField("Reserved2",0,7),
  7561.                    BitField("ExtendedSecurity",0,1),
  7562.                    FlagsField("CompBulk",0,2,"CB"),
  7563.                    BitField("Reserved3",0,5),
  7564.                    # There have been 127490112000000000 tenths of micro-seconds between 1st january 1601 and 1st january 2005. 127490112000000000=0x1C4EF94D6228000, so ServerTimeHigh=0xD6228000 and ServerTimeLow=0x1C4EF94.
  7565.                    LEIntField("ServerTimeHigh",0xD6228000L),
  7566.                    LEIntField("ServerTimeLow",0x1C4EF94),
  7567.                    LEShortField("ServerTimeZone",0x3c),
  7568.                    ByteField("EncryptionKeyLength",8),
  7569.                    LEShortField("ByteCount",24),
  7570.                    BitField("EncryptionKey",0,64),
  7571.                    StrNullField("DomainName","WORKGROUP"),
  7572.                    StrNullField("ServerName","RMFF1")]
  7573.     
  7574. # SMBNegociate Protocol Response No Security No Key
  7575. class SMBNegociate_Protocol_Response_No_Security_No_Key(Packet):
  7576.     namez="SMBNegociate Protocol Response No Security No Key"
  7577.     fields_desc = [StrFixedLenField("Start","\xffSMB",4),
  7578.                    ByteEnumField("Command",0x72,{0x72:"SMB_COM_NEGOTIATE"}),
  7579.                    ByteField("Error_Class",0),
  7580.                    ByteField("Reserved",0),
  7581.                    LEShortField("Error_Code",0),
  7582.                    ByteField("Flags",0x98),
  7583.                    LEShortField("Flags2",0x0000),
  7584.                    LEShortField("PIDHigh",0x0000),
  7585.                    LELongField("Signature",0x0),
  7586.                    LEShortField("Unused",0x0),
  7587.                    LEShortField("TID",0),
  7588.                    LEShortField("PID",1),
  7589.                    LEShortField("UID",0),
  7590.                    LEShortField("MID",2),
  7591.                    ByteField("WordCount",17),
  7592.                    LEShortField("DialectIndex",7),
  7593.                    ByteField("SecurityMode",0x03),
  7594.                    LEShortField("MaxMpxCount",50),
  7595.                    LEShortField("MaxNumberVC",1),
  7596.                    LEIntField("MaxBufferSize",16144),
  7597.                    LEIntField("MaxRawSize",65536),
  7598.                    LEIntField("SessionKey",0x0000),
  7599.                    LEShortField("ServerCapabilities",0xf3f9),
  7600.                    BitField("UnixExtensions",0,1),
  7601.                    BitField("Reserved2",0,7),
  7602.                    BitField("ExtendedSecurity",0,1),
  7603.                    FlagsField("CompBulk",0,2,"CB"),
  7604.                    BitField("Reserved3",0,5),
  7605.                    # There have been 127490112000000000 tenths of micro-seconds between 1st january 1601 and 1st january 2005. 127490112000000000=0x1C4EF94D6228000, so ServerTimeHigh=0xD6228000 and ServerTimeLow=0x1C4EF94.
  7606.                    LEIntField("ServerTimeHigh",0xD6228000L),
  7607.                    LEIntField("ServerTimeLow",0x1C4EF94),
  7608.                    LEShortField("ServerTimeZone",0x3c),
  7609.                    ByteField("EncryptionKeyLength",0),
  7610.                    LEShortField("ByteCount",16),
  7611.                    StrNullField("DomainName","WORKGROUP"),
  7612.                    StrNullField("ServerName","RMFF1")]
  7613.     
  7614. # Session Setup AndX Request
  7615. class SMBSession_Setup_AndX_Request(Packet):
  7616.     name="Session Setup AndX Request"
  7617.     fields_desc=[StrFixedLenField("Start","\xffSMB",4),
  7618.                 ByteEnumField("Command",0x73,{0x73:"SMB_COM_SESSION_SETUP_ANDX"}),
  7619.                  ByteField("Error_Class",0),
  7620.                  ByteField("Reserved",0),
  7621.                  LEShortField("Error_Code",0),
  7622.                  ByteField("Flags",0x18),
  7623.                  LEShortField("Flags2",0x0001),
  7624.                  LEShortField("PIDHigh",0x0000),
  7625.                  LELongField("Signature",0x0),
  7626.                  LEShortField("Unused",0x0),
  7627.                  LEShortField("TID",0),
  7628.                  LEShortField("PID",1),
  7629.                  LEShortField("UID",0),
  7630.                  LEShortField("MID",2),
  7631.                  ByteField("WordCount",13),
  7632.                  ByteEnumField("AndXCommand",0x75,{0x75:"SMB_COM_TREE_CONNECT_ANDX"}),
  7633.                  ByteField("Reserved2",0),
  7634.                  LEShortField("AndXOffset",96),
  7635.                  LEShortField("MaxBufferS",2920),
  7636.                  LEShortField("MaxMPXCount",50),
  7637.                  LEShortField("VCNumber",0),
  7638.                  LEIntField("SessionKey",0),
  7639.                  LEFieldLenField("ANSIPasswordLength",None,"ANSIPassword",shift=0),
  7640.                  LEShortField("UnicodePasswordLength",0),
  7641.                  LEIntField("Reserved3",0),
  7642.                  LEShortField("ServerCapabilities",0x05),
  7643.                  BitField("UnixExtensions",0,1),
  7644.                  BitField("Reserved4",0,7),
  7645.                  BitField("ExtendedSecurity",0,1),
  7646.                  BitField("CompBulk",0,2),
  7647.                  BitField("Reserved5",0,5),
  7648.                  LEShortField("ByteCount",35),
  7649.                  StrLenField("ANSIPassword", "Pass","ANSIPasswordLength"),
  7650.                  StrNullField("Account","GUEST"),
  7651.                  StrNullField("PrimaryDomain",  ""),
  7652.                  StrNullField("NativeOS","Windows 4.0"),
  7653.                  StrNullField("NativeLanManager","Windows 4.0"),
  7654.                  ByteField("WordCount2",4),
  7655.                  ByteEnumField("AndXCommand2",0xFF,{0xFF:"SMB_COM_NONE"}),
  7656.                  ByteField("Reserved6",0),
  7657.                  LEShortField("AndXOffset2",0),
  7658.                  LEShortField("Flags3",0x2),
  7659.                  LEShortField("PasswordLength",0x1),
  7660.                  LEShortField("ByteCount2",18),
  7661.                  ByteField("Password",0),
  7662.                  StrNullField("Path","\\\\WIN2K\\IPC$"),
  7663.                  StrNullField("Service","IPC")]
  7664.  
  7665. # Session Setup AndX Response
  7666. class SMBSession_Setup_AndX_Response(Packet):
  7667.     name="Session Setup AndX Response"
  7668.     fields_desc=[StrFixedLenField("Start","\xffSMB",4),
  7669.                  ByteEnumField("Command",0x73,{0x73:"SMB_COM_SESSION_SETUP_ANDX"}),
  7670.                  ByteField("Error_Class",0),
  7671.                  ByteField("Reserved",0),
  7672.                  LEShortField("Error_Code",0),
  7673.                  ByteField("Flags",0x90),
  7674.                  LEShortField("Flags2",0x1001),
  7675.                  LEShortField("PIDHigh",0x0000),
  7676.                  LELongField("Signature",0x0),
  7677.                  LEShortField("Unused",0x0),
  7678.                  LEShortField("TID",0),
  7679.                  LEShortField("PID",1),
  7680.                  LEShortField("UID",0),
  7681.                  LEShortField("MID",2),
  7682.                  ByteField("WordCount",3),
  7683.                  ByteEnumField("AndXCommand",0x75,{0x75:"SMB_COM_TREE_CONNECT_ANDX"}),
  7684.                  ByteField("Reserved2",0),
  7685.                  LEShortField("AndXOffset",66),
  7686.                  LEShortField("Action",0),
  7687.                  LEShortField("ByteCount",25),
  7688.                  StrNullField("NativeOS","Windows 4.0"),
  7689.                  StrNullField("NativeLanManager","Windows 4.0"),
  7690.                  StrNullField("PrimaryDomain",""),
  7691.                  ByteField("WordCount2",3),
  7692.                  ByteEnumField("AndXCommand2",0xFF,{0xFF:"SMB_COM_NONE"}),
  7693.                  ByteField("Reserved3",0),
  7694.                  LEShortField("AndXOffset2",80),
  7695.                  LEShortField("OptionalSupport",0x01),
  7696.                  LEShortField("ByteCount2",5),
  7697.                  StrNullField("Service","IPC"),
  7698.                  StrNullField("NativeFileSystem","")]
  7699.  
  7700. class MobileIP(Packet):
  7701.     name = "Mobile IP (RFC3344)"
  7702.     fields_desc = [ ByteEnumField("type", 1, {1:"RRQ", 3:"RRP"}) ]
  7703.  
  7704. class MobileIPRRQ(Packet):
  7705.     name = "Mobile IP Registration Request (RFC3344)"
  7706.     fields_desc = [ XByteField("flags", 0),
  7707.                     ShortField("lifetime", 180),
  7708.                     IPField("homeaddr", "0.0.0.0"),
  7709.                     IPField("haaddr", "0.0.0.0"),
  7710.                     IPField("coaddr", "0.0.0.0"),
  7711.                     Field("id", "", "64s") ]
  7712.  
  7713. class MobileIPRRP(Packet):
  7714.     name = "Mobile IP Registration Reply (RFC3344)"
  7715.     fields_desc = [ ByteField("code", 0),
  7716.                     ShortField("lifetime", 180),
  7717.                     IPField("homeaddr", "0.0.0.0"),
  7718.                     IPField("haaddr", "0.0.0.0"),
  7719.                     Field("id", "", "64s") ]
  7720.  
  7721. class MobileIPTunnelData(Packet):
  7722.     name = "Mobile IP Tunnel Data Message (RFC3519)"
  7723.     fields_desc = [ ByteField("nexthdr", 4),
  7724.                     ShortField("res", 0) ]
  7725.  
  7726.  
  7727.  
  7728. #################
  7729. ## Bind layers ##
  7730. #################
  7731.  
  7732.  
  7733. def bind_bottom_up(lower, upper, fval):
  7734.     lower.payload_guess = lower.payload_guess[:]
  7735.     lower.payload_guess.append((fval, upper))
  7736.     
  7737.  
  7738. def bind_top_down(lower, upper, fval):
  7739.     upper.overload_fields = upper.overload_fields.copy()
  7740.     upper.overload_fields[lower] = fval
  7741.     
  7742. def bind_layers(lower, upper, fval):
  7743.     bind_top_down(lower, upper, fval)
  7744.     bind_bottom_up(lower, upper, fval)
  7745.  
  7746. layer_bonds = [ ( Dot3,   LLC,      { } ),
  7747.                 ( GPRS,   IP,       { } ),
  7748.                 ( PrismHeader, Dot11, { }),
  7749.                 ( Dot11,  LLC,      { "type" : 2 } ),
  7750.                 ( PPP,    IP,       { "proto" : 0x0021 } ),
  7751.                 ( Ether,  LLC,      { "type" : 0x007a } ),
  7752.                 ( Ether,  Dot1Q,    { "type" : 0x8100 } ),
  7753.                 ( Ether,  Ether,    { "type" : 0x0001 } ),
  7754.                 ( Ether,  ARP,      { "type" : 0x0806 } ),
  7755.                 ( Ether,  IP,       { "type" : 0x0800 } ),
  7756.                 ( Ether,  EAPOL,    { "type" : 0x888e } ),
  7757.                 ( Ether,  EAPOL,    { "type" : 0x888e, "dst" : "01:80:c2:00:00:03" } ),
  7758.                 ( Ether,  PPPoED,   { "type" : 0x8863 } ),
  7759.                 ( Ether,  PPPoE,    { "type" : 0x8864 } ),
  7760.                 ( CookedLinux,  LLC,      { "proto" : 0x007a } ),
  7761.                 ( CookedLinux,  Dot1Q,    { "proto" : 0x8100 } ),
  7762.                 ( CookedLinux,  Ether,    { "proto" : 0x0001 } ),
  7763.                 ( CookedLinux,  ARP,      { "proto" : 0x0806 } ),
  7764.                 ( CookedLinux,  IP,       { "proto" : 0x0800 } ),
  7765.                 ( CookedLinux,  EAPOL,    { "proto" : 0x888e } ),
  7766.                 ( CookedLinux,  PPPoED,   { "proto" : 0x8863 } ),
  7767.                 ( CookedLinux,  PPPoE,    { "proto" : 0x8864 } ),
  7768.                 ( GRE,    LLC,      { "proto" : 0x007a } ),
  7769.                 ( GRE,    Dot1Q,    { "proto" : 0x8100 } ),
  7770.                 ( GRE,    Ether,    { "proto" : 0x0001 } ),
  7771.                 ( GRE,    ARP,      { "proto" : 0x0806 } ),
  7772.                 ( GRE,    IP,       { "proto" : 0x0800 } ),
  7773.                 ( GRE,    EAPOL,    { "proto" : 0x888e } ),
  7774.                 ( PPPoE,  PPP,      { "code" : 0x00 } ),
  7775.                 ( EAPOL,  EAP,      { "type" : EAPOL.EAP_PACKET } ),
  7776.                 ( LLC,    STP,      { "dsap" : 0x42 , "ssap" : 0x42, "ctrl":3 } ),
  7777.                 ( LLC,    SNAP,     { "dsap" : 0xAA , "ssap" : 0xAA, "ctrl":3 } ),
  7778.                 ( SNAP,   Dot1Q,    { "code" : 0x8100 } ),
  7779.                 ( SNAP,   Ether,    { "code" : 0x0001 } ),
  7780.                 ( SNAP,   ARP,      { "code" : 0x0806 } ),
  7781.                 ( SNAP,   IP,       { "code" : 0x0800 } ),
  7782.                 ( SNAP,   EAPOL,    { "code" : 0x888e } ),
  7783.                 ( IPerror,IPerror,  { "frag" : 0, "proto" : socket.IPPROTO_IP   } ),
  7784.                 ( IPerror,ICMPerror,{ "frag" : 0, "proto" : socket.IPPROTO_ICMP } ),
  7785.                 ( IPerror,TCPerror, { "frag" : 0, "proto" : socket.IPPROTO_TCP  } ),
  7786.                 ( IPerror,UDPerror, { "frag" : 0, "proto" : socket.IPPROTO_UDP  } ),
  7787.                 ( IP,     IP,       { "frag" : 0, "proto" : socket.IPPROTO_IP   } ),
  7788.                 ( IP,     ICMP,     { "frag" : 0, "proto" : socket.IPPROTO_ICMP } ),
  7789.                 ( IP,     TCP,      { "frag" : 0, "proto" : socket.IPPROTO_TCP  } ),
  7790.                 ( IP,     UDP,      { "frag" : 0, "proto" : socket.IPPROTO_UDP  } ),
  7791.                 ( IP,     GRE,      { "frag" : 0, "proto" : socket.IPPROTO_GRE  } ),
  7792.                 ( UDP,    MGCP,     { "dport" : 2727 } ),
  7793.                 ( UDP,    MGCP,     { "sport" : 2727 } ),
  7794.                 ( UDP,    DNS,      { "dport" : 53 } ),
  7795.                 ( UDP,    DNS,      { "sport" : 53 } ),
  7796.                 ( UDP,    ISAKMP,   { "sport" : 500, "dport" : 500 } ),
  7797.                 ( UDP,    HSRP,     { "sport" : 1985, "dport" : 1985} ),
  7798.                 ( UDP,    NTP,      { "sport" : 123, "dport" : 123 } ),
  7799.                 ( UDP,    BOOTP,    { "sport" : 68, "dport" : 67 } ),
  7800.                 ( UDP,    BOOTP,    { "sport" : 67, "dport" : 68 } ),
  7801.                 ( BOOTP,  DHCP,     { "options" : dhcpmagic } ),
  7802.                 ( UDP,    RIP,      { "sport" : 520 } ),
  7803.                 ( UDP,    RIP,      { "dport" : 520 } ),
  7804.                 ( RIP,    RIPEntry, { } ),
  7805.                 ( RIPEntry,RIPEntry,{ } ),
  7806.                 ( Dot11, Dot11AssoReq,    { "type" : 0, "subtype" : 0 } ),
  7807.                 ( Dot11, Dot11AssoResp,   { "type" : 0, "subtype" : 1 } ),
  7808.                 ( Dot11, Dot11ReassoReq,  { "type" : 0, "subtype" : 2 } ),
  7809.                 ( Dot11, Dot11ReassoResp, { "type" : 0, "subtype" : 3 } ),
  7810.                 ( Dot11, Dot11ProbeReq,   { "type" : 0, "subtype" : 4 } ),
  7811.                 ( Dot11, Dot11ProbeResp,  { "type" : 0, "subtype" : 5 } ),
  7812.                 ( Dot11, Dot11Beacon,     { "type" : 0, "subtype" : 8 } ),
  7813.                 ( Dot11, Dot11ATIM ,      { "type" : 0, "subtype" : 9 } ),
  7814.                 ( Dot11, Dot11Disas ,     { "type" : 0, "subtype" : 10 } ),
  7815.                 ( Dot11, Dot11Auth,       { "type" : 0, "subtype" : 11 } ),
  7816.                 ( Dot11, Dot11Deauth,     { "type" : 0, "subtype" : 12 } ),
  7817.                 ( Dot11Beacon, Dot11Elt,     {} ),
  7818.                 ( Dot11AssoReq, Dot11Elt,    {} ),
  7819.                 ( Dot11AssoResp, Dot11Elt,   {} ),
  7820.                 ( Dot11ReassoReq, Dot11Elt,  {} ),
  7821.                 ( Dot11ReassoResp, Dot11Elt, {} ),
  7822.                 ( Dot11ProbeReq, Dot11Elt,   {} ),
  7823.                 ( Dot11ProbeResp, Dot11Elt,  {} ),
  7824.                 ( Dot11Auth, Dot11Elt,       {} ),
  7825.                 ( Dot11Elt, Dot11Elt,        {} ),
  7826.                 ( TCP,      Skinny,          { "dport": 2000 } ),
  7827.                 ( TCP,      Skinny,          { "sport": 2000 } ),
  7828.                 ( UDP,      SebekHead,       { "sport" : 1101 } ),
  7829.                 ( UDP,      SebekHead,       { "dport" : 1101 } ),
  7830.                 ( UDP,      SebekHead,       { "sport" : 1101,
  7831.                                                "dport" : 1101 } ),
  7832.                 ( SebekHead, SebekV1,        { "version" : 1 } ),
  7833.                 ( SebekHead, SebekV2Sock,    { "version" : 2,
  7834.                                                "type" : 2 } ),
  7835.                 ( SebekHead, SebekV2,        { "version" : 2 } ),
  7836.                 ( SebekHead, SebekV3Sock,    { "version" : 3,
  7837.                                                "type" : 2 } ),
  7838.                 ( SebekHead, SebekV3,        { "version" : 3 } ),
  7839.                 ( CookedLinux,  IrLAPHead,   { "proto" : 0x0017 } ),
  7840.                 ( IrLAPHead, IrLAPCommand,   { "Type" : 1} ),
  7841.                 ( IrLAPCommand, IrLMP,       {} ),
  7842.                 (UDP, NBNSQueryRequest, {"dport" : 137 }),
  7843.                 (UDP, NBNSRequest, {"dport" : 137 }),
  7844.                 (UDP, NBNSQueryResponse, {"sport" : 137}),
  7845.                 (UDP, NBNSQueryResponseNegative, {"sport" : 137}),
  7846.                 (UDP, NBNSNodeStatusResponse, {"sport" : 137}),
  7847.                 (NBNSNodeStatusResponse, NBNSNodeStatusResponseService, {}),
  7848.                 (NBNSNodeStatusResponse, NBNSNodeStatusResponseService, {}),
  7849.                 (NBNSNodeStatusResponseService, NBNSNodeStatusResponseService, {}),
  7850.                 (NBNSNodeStatusResponseService, NBNSNodeStatusResponseEnd, {}),
  7851.                 (UDP, NBNSWackResponse, {"sport" : 137}),
  7852.                 (UDP,NBTDatagram,{ "dport":138}),
  7853.                 (TCP,NBTSession,{"dport":139}),
  7854.                 (NBTSession, SMBNegociate_Protocol_Request_Header,{}),
  7855.                 (SMBNegociate_Protocol_Request_Header,SMBNegociate_Protocol_Request_Tail,{}),
  7856.                 (SMBNegociate_Protocol_Request_Tail,SMBNegociate_Protocol_Request_Tail,{}),
  7857.                 (NBTSession, SMBNegociate_Protocol_Response_Advanced_Security,{"ExtendedSecurity":1}),
  7858.                 (NBTSession, SMBNegociate_Protocol_Response_No_Security,{"ExtendedSecurity":0,"EncryptionKeyLength":8 }),
  7859.                 (NBTSession, SMBNegociate_Protocol_Response_No_Security_No_Key,{"ExtendedSecurity":0,"EncryptionKeyLength":0 }),
  7860.                 (NBTSession, SMBSession_Setup_AndX_Request,{}),
  7861.                 (NBTSession, SMBSession_Setup_AndX_Response,{}),
  7862.  
  7863.                 (HCI_Hdr,      HCI_ACL_Hdr,    {"type":2}),
  7864.                 (HCI_Hdr,      Raw,    {}),
  7865.                 (HCI_ACL_Hdr,  L2CAP_Hdr, {}),
  7866.                 (L2CAP_Hdr,    L2CAP_CmdHdr, {"cid":1}),
  7867.                 (L2CAP_CmdHdr, L2CAP_CmdRej, {"code":1}),
  7868.                 (L2CAP_CmdHdr, L2CAP_ConnReq, {"code":2}),
  7869.                 (L2CAP_CmdHdr, L2CAP_ConnResp, {"code":3}),
  7870.                 (L2CAP_CmdHdr, L2CAP_ConfReq, {"code":4}),
  7871.                 (L2CAP_CmdHdr, L2CAP_ConfResp, {"code":5}),
  7872.                 (L2CAP_CmdHdr, L2CAP_DisconnReq, {"code":6}),
  7873.                 (L2CAP_CmdHdr, L2CAP_DisconnResp, {"code":7}),
  7874.                 (L2CAP_CmdHdr, L2CAP_InfoReq, {"code":10}),
  7875.                 (L2CAP_CmdHdr, L2CAP_InfoResp, {"code":11}),
  7876.                 ( UDP,      MobileIP,    { "sport" : 434 } ),
  7877.                 ( UDP,      MobileIP,    { "dport" : 434 } ),
  7878.                 ( MobileIP, MobileIPRRQ, { "type"  : 1 } ),
  7879.                 ( MobileIP, MobileIPRRP, { "type"  : 3 } ),
  7880.                 ( MobileIP, MobileIPTunnelData, { "type" : 4 } ),
  7881.                 ( MobileIPTunnelData, IP, { "nexthdr" : 4 } ),
  7882.  
  7883.                 ]
  7884.  
  7885. for l in layer_bonds:
  7886.     bind_layers(*l)
  7887. del(l)
  7888.                 
  7889.  
  7890. ###################
  7891. ## Fragmentation ##
  7892. ###################
  7893.  
  7894. def fragment(pkt, fragsize=1480):
  7895.     fragsize = (fragsize+7)/8*8
  7896.     pkt = pkt.copy()
  7897.     pkt.flags = "MF"
  7898.     lst = []
  7899.     for p in pkt:
  7900.         s = str(p.payload)
  7901.         nb = (len(s)+fragsize-1)/fragsize
  7902.         for i in range(nb):            
  7903.             q = p.copy()
  7904.             del(q.payload)
  7905.             r = Raw(load=s[i*fragsize:(i+1)*fragsize])
  7906.             r.overload_fields = p.payload.overload_fields.copy()
  7907.             if i == nb-1:
  7908.                 q.flags=0
  7909.             q.frag = i*fragsize/8
  7910.             q.add_payload(r)
  7911.             lst.append(q)
  7912.     return lst
  7913.  
  7914.  
  7915. ###################
  7916. ## Super sockets ##
  7917. ###################
  7918.  
  7919.  
  7920. # According to libdnet
  7921. LLTypes = { ARPHDR_ETHER : Ether,
  7922.             ARPHDR_METRICOM : Ether,
  7923.             ARPHDR_LOOPBACK : Ether,
  7924.             12 : IP,
  7925.         101 : IP,
  7926.             801 : Dot11,
  7927.             802 : PrismHeader,
  7928.             105 : Dot11,
  7929.             113 : CookedLinux,
  7930.             119 : PrismHeader, # for atheros
  7931.             144 : CookedLinux, # called LINUX_IRDA, similar to CookedLinux
  7932.             783 : IrLAPHead,
  7933.             0xB1E70073L : HCI_Hdr, # I invented this one
  7934.             }
  7935.  
  7936. LLNumTypes = { Ether : ARPHDR_ETHER,
  7937.                IP  : 12,
  7938.                IP  : 101,
  7939.                Dot11  : 801,
  7940.                PrismHeader : 802,
  7941.                Dot11 : 105,
  7942.                CookedLinux : 113,
  7943.                CookedLinux : 144,
  7944.                IrLAPHead : 783
  7945.             }
  7946.  
  7947. L3Types = { ETH_P_IP : IP,
  7948.             ETH_P_ARP : ARP,
  7949.             ETH_P_ALL : IP
  7950.             }
  7951.  
  7952.  
  7953.  
  7954. class SuperSocket:
  7955.     closed=0
  7956.     def __init__(self, family=socket.AF_INET,type=socket.SOCK_STREAM, proto=0):
  7957.         self.ins = socket.socket(family, type, proto)
  7958.         self.outs = self.ins
  7959.         self.promisc=None
  7960.     def send(self, x):
  7961.         return self.outs.send(str(x))
  7962.     def recv(self, x):
  7963.         return Raw(self.ins.recv(x))
  7964.     def fileno(self):
  7965.         return self.ins.fileno()
  7966.     def close(self):
  7967.         if self.closed:
  7968.             return
  7969.         self.closed=1
  7970.         if self.ins != self.outs:
  7971.             if self.outs and self.outs.fileno() != -1:
  7972.                 self.outs.close()
  7973.         if self.ins and self.ins.fileno() != -1:
  7974.             self.ins.close()
  7975.     def bind_in(self, addr):
  7976.         self.ins.bind(addr)
  7977.     def bind_out(self, addr):
  7978.         self.outs.bind(addr)
  7979.  
  7980.  
  7981. class L3RawSocket(SuperSocket):
  7982.     def __init__(self, type = ETH_P_IP, filter=None, iface=None, promisc=None, nofilter=0):
  7983.         self.outs = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_RAW)
  7984.         self.outs.setsockopt(socket.SOL_IP, socket.IP_HDRINCL, 1)
  7985.         self.ins = socket.socket(socket.AF_PACKET, socket.SOCK_RAW, socket.htons(type))
  7986.     def recv(self, x):
  7987.         return Ether(self.ins.recv(x)).payload
  7988.     def send(self, x):
  7989.         try:
  7990.             self.outs.sendto(str(x),(x.dst,0))
  7991.         except socket.error,msg:
  7992.             log_runtime.error(msg)
  7993.         
  7994.  
  7995.  
  7996. class L3PacketSocket(SuperSocket):
  7997.     def __init__(self, type = ETH_P_ALL, filter=None, promisc=None, iface=None, nofilter=0):
  7998.         self.type = type
  7999.         self.ins = socket.socket(socket.AF_PACKET, socket.SOCK_RAW, socket.htons(type))
  8000.         self.ins.setsockopt(socket.SOL_SOCKET, socket.SO_RCVBUF, 0)
  8001.         if not nofilter:
  8002.             if conf.except_filter:
  8003.                 if filter:
  8004.                     filter = "(%s) and not (%s)" % (filter, conf.except_filter)
  8005.                 else:
  8006.                     filter = "not (%s)" % conf.except_filter
  8007.             if filter is not None:
  8008.                 attach_filter(self.ins, filter)
  8009.         self.ins.setsockopt(socket.SOL_SOCKET, socket.SO_RCVBUF, 2**30)
  8010.         self.outs = socket.socket(socket.AF_PACKET, socket.SOCK_RAW, socket.htons(type))
  8011.         self.outs.setsockopt(socket.SOL_SOCKET, socket.SO_SNDBUF, 2**30)
  8012.         if promisc is None:
  8013.             promisc = conf.promisc
  8014.         self.promisc = promisc
  8015.         if iface is None:
  8016.             self.iff = get_if_list()
  8017.         else:
  8018.             if iface.__class__ is list:
  8019.                 self.iff = iface
  8020.             else:
  8021.                 self.iff = [iface]
  8022.         if self.promisc:
  8023.             for i in self.iff:
  8024.                 set_promisc(self.ins, i)
  8025.     def close(self):
  8026.         if self.closed:
  8027.             return
  8028.         self.closed=1
  8029.         if self.promisc:
  8030.             for i in self.iff:
  8031.                 set_promisc(self.ins, i, 0)
  8032.         SuperSocket.close(self)
  8033.     def recv(self, x):
  8034.         pkt, sa_ll = self.ins.recvfrom(x)
  8035.         if sa_ll[2] == socket.PACKET_OUTGOING:
  8036.             return None
  8037.         if LLTypes.has_key(sa_ll[3]):
  8038.             cls = LLTypes[sa_ll[3]]
  8039.             lvl = 2
  8040.         elif L3Types.has_key(sa_ll[1]):
  8041.             cls = L3Types[sa_ll[1]]
  8042.             lvl = 3
  8043.         else:
  8044.             warning("Unable to guess type (interface=%s protocol=%#x family=%i). Using Ethernet" % (sa_ll[0],sa_ll[1],sa_ll[3]))
  8045.             cls = Ether
  8046.             lvl = 2
  8047.  
  8048.         try:
  8049.             pkt = cls(pkt)
  8050.         except:
  8051.             if conf.debug_dissector:
  8052.                 raise
  8053.             pkt = Raw(pkt)
  8054.         if lvl == 2:
  8055.             pkt = pkt.payload
  8056.         return pkt
  8057.     
  8058.     def send(self, x):
  8059.         if isinstance(x, IPv6):
  8060.             iff,a,gw = conf.route6.route(x.dst)
  8061.         elif hasattr(x,"dst"):
  8062.             iff,a,gw = conf.route.route(x.dst)
  8063.         else:
  8064.             iff = conf.iface
  8065.         sdto = (iff, self.type)
  8066.         self.outs.bind(sdto)
  8067.         sn = self.outs.getsockname()
  8068.         if sn[3] == ARPHDR_PPP:
  8069.             sdto = (iff, ETH_P_IP)
  8070.         elif LLTypes.has_key(sn[3]):
  8071.             x = LLTypes[sn[3]]()/x
  8072.         self.outs.sendto(str(x), sdto)
  8073.  
  8074.  
  8075.  
  8076. class L2Socket(SuperSocket):
  8077.     def __init__(self, iface = None, type = ETH_P_ALL, filter=None, nofilter=0):
  8078.         if iface is None:
  8079.             iface = conf.iface
  8080.         self.ins = socket.socket(socket.AF_PACKET, socket.SOCK_RAW, socket.htons(type))
  8081.         self.ins.setsockopt(socket.SOL_SOCKET, socket.SO_RCVBUF, 0)
  8082.         if not nofilter: 
  8083.             if conf.except_filter:
  8084.                 if filter:
  8085.                     filter = "(%s) and not (%s)" % (filter, conf.except_filter)
  8086.                 else:
  8087.                     filter = "not (%s)" % conf.except_filter
  8088.             if filter is not None:
  8089.                 attach_filter(self.ins, filter)
  8090.         self.ins.bind((iface, type))
  8091.         self.ins.setsockopt(socket.SOL_SOCKET, socket.SO_RCVBUF, 2**30)
  8092.         self.outs = self.ins
  8093.         self.outs.setsockopt(socket.SOL_SOCKET, socket.SO_SNDBUF, 2**30)
  8094.         sa_ll = self.outs.getsockname()
  8095.         if LLTypes.has_key(sa_ll[3]):
  8096.             self.LL = LLTypes[sa_ll[3]]
  8097.         elif L3Types.has_key(sa_ll[1]):
  8098.             self.LL = L3Types[sa_ll[1]]
  8099.         else:
  8100.             warning("Unable to guess type (interface=%s protocol=%#x family=%i). Using Ethernet" % (sa_ll[0],sa_ll[1],sa_ll[3]))
  8101.             self.LL = Ether
  8102.             
  8103.     def recv(self, x):
  8104.         pkt, sa_ll = self.ins.recvfrom(x)
  8105.         if sa_ll[2] == socket.PACKET_OUTGOING:
  8106.             return None
  8107.         try:
  8108.             q = self.LL(pkt)
  8109.         except:
  8110.             if conf.debug_dissector:
  8111.                 raise
  8112.             q = Raw(pkt)
  8113.         return q
  8114.  
  8115.  
  8116. class L2ListenSocket(SuperSocket):
  8117.     def __init__(self, iface = None, type = ETH_P_ALL, promisc=None, filter=None, nofilter=0):
  8118.         self.type = type
  8119.         self.outs = None
  8120.         self.ins = socket.socket(socket.AF_PACKET, socket.SOCK_RAW, socket.htons(type))
  8121.         self.ins.setsockopt(socket.SOL_SOCKET, socket.SO_RCVBUF, 0)
  8122.         if iface is not None:
  8123.             self.ins.bind((iface, type))
  8124.         if not nofilter:
  8125.             if conf.except_filter:
  8126.                 if filter:
  8127.                     filter = "(%s) and not (%s)" % (filter, conf.except_filter)
  8128.                 else:
  8129.                     filter = "not (%s)" % conf.except_filter
  8130.             if filter is not None:
  8131.                 attach_filter(self.ins, filter)
  8132.         if promisc is None:
  8133.             promisc = conf.sniff_promisc
  8134.         self.promisc = promisc
  8135.         if iface is None:
  8136.             self.iff = get_if_list()
  8137.         else:
  8138.             if iface.__class__ is list:
  8139.                 self.iff = iface
  8140.             else:
  8141.                 self.iff = [iface]
  8142.         if self.promisc:
  8143.             for i in self.iff:
  8144.                 set_promisc(self.ins, i)
  8145.         self.ins.setsockopt(socket.SOL_SOCKET, socket.SO_RCVBUF, 2**30)
  8146.     def close(self):
  8147.         if self.promisc:
  8148.             for i in self.iff:
  8149.                 set_promisc(self.ins, i, 0)
  8150.         SuperSocket.close(self)
  8151.  
  8152.     def recv(self, x):
  8153.         pkt, sa_ll = self.ins.recvfrom(x)
  8154.         if LLTypes.has_key(sa_ll[3]):
  8155.             cls = LLTypes[sa_ll[3]]
  8156.         elif L3Types.has_key(sa_ll[1]):
  8157.             cls = L3Types[sa_ll[1]]
  8158.         else:
  8159.             warning("Unable to guess type (interface=%s protocol=%#x family=%i). Using Ethernet" % (sa_ll[0],sa_ll[1],sa_ll[3]))
  8160.             cls = Ether
  8161.  
  8162.         try:
  8163.             pkt = cls(pkt)
  8164.         except:
  8165.             if conf.debug_dissector:
  8166.                 raise
  8167.             pkt = Raw(pkt)
  8168.         return pkt
  8169.     
  8170.     def send(self, x):
  8171.         raise Exception("Can't send anything with L2ListenSocket")
  8172.  
  8173.  
  8174.  
  8175. class L3dnetSocket(SuperSocket):
  8176.     def __init__(self, type = ETH_P_ALL, filter=None, promisc=None, iface=None, nofilter=0):
  8177.         self.iflist = {}
  8178.         self.ins = pcap.pcapObject()
  8179.         if iface is None:
  8180.             iface = conf.iface
  8181.         self.iface = iface
  8182.         self.ins.open_live(iface, 1600, 0, 100)
  8183.         try:
  8184.             ioctl(self.ins.fileno(),BIOCIMMEDIATE,struct.pack("I",1))
  8185.         except:
  8186.             pass
  8187.         if nofilter:
  8188.             if type != ETH_P_ALL:  # PF_PACKET stuff. Need to emulate this for pcap
  8189.                 filter = "ether proto %i" % type
  8190.             else:
  8191.                 filter = None
  8192.         else:
  8193.             if conf.except_filter:
  8194.                 if filter:
  8195.                     filter = "(%s) and not (%s)" % (filter, conf.except_filter)
  8196.                 else:
  8197.                     filter = "not (%s)" % conf.except_filter
  8198.             if type != ETH_P_ALL:  # PF_PACKET stuff. Need to emulate this for pcap
  8199.                 if filter:
  8200.                     filter = "(ether proto %i) and (%s)" % (type,filter)
  8201.                 else:
  8202.                     filter = "ether proto %i" % type
  8203.         if filter:
  8204.             self.ins.setfilter(filter, 0, 0)
  8205.     def send(self, x):
  8206.         if isinstance(x, IPv6):
  8207.             iff,a,gw = conf.route6.route(x.dst)
  8208.         elif hasattr(x,"dst"):
  8209.             iff,a,gw = conf.route.route(x.dst)
  8210.         else:
  8211.             iff = conf.iface
  8212.         ifs = self.iflist.get(iff)
  8213.         if ifs is None:
  8214.             self.iflist[iff] = ifs = dnet.eth(iff)
  8215.         ifs.send(str(Ether()/x))
  8216.     def recv(self,x=MTU):
  8217.         ll = self.ins.datalink()
  8218.         if LLTypes.has_key(ll):
  8219.             cls = LLTypes[ll]
  8220.         else:
  8221.             warning("Unable to guess datalink type (interface=%s linktype=%i). Using Ethernet" % (self.iface, ll))
  8222.             cls = Ether
  8223.  
  8224.         pkt = self.ins.next()
  8225.         if pkt is not None:
  8226.             pkt = pkt[1]
  8227.         if pkt is None:
  8228.             return
  8229.  
  8230.         try:
  8231.             pkt = cls(pkt)
  8232.         except:
  8233.             if conf.debug_dissector:
  8234.                 raise
  8235.             pkt = Raw(pkt)
  8236.         return pkt.payload
  8237.  
  8238.     def nonblock_recv(self):
  8239.         self.ins.setnonblock(1)
  8240.         p = self.recv()
  8241.         self.ins.setnonblock(0)
  8242.         return p
  8243.  
  8244.     def close(self):
  8245.         if hasattr(self, "ins"):
  8246.             del(self.ins)
  8247.         if hasattr(self, "outs"):
  8248.             del(self.outs)
  8249.  
  8250. class L2dnetSocket(SuperSocket):
  8251.     def __init__(self, iface = None, type = ETH_P_ALL, filter=None, nofilter=0):
  8252.         if iface is None:
  8253.             iface = conf.iface
  8254.         self.iface = iface
  8255.         self.ins = pcap.pcapObject()
  8256.         self.ins.open_live(iface, 1600, 0, 100)
  8257.         try:
  8258.             ioctl(self.ins.fileno(),BIOCIMMEDIATE,struct.pack("I",1))
  8259.         except:
  8260.             pass
  8261.         if nofilter:
  8262.             if type != ETH_P_ALL:  # PF_PACKET stuff. Need to emulate this for pcap
  8263.                 filter = "ether proto %i" % type
  8264.             else:
  8265.                 filter = None
  8266.         else:
  8267.             if conf.except_filter:
  8268.                 if filter:
  8269.                     filter = "(%s) and not (%s)" % (filter, conf.except_filter)
  8270.                 else:
  8271.                     filter = "not (%s)" % conf.except_filter
  8272.             if type != ETH_P_ALL:  # PF_PACKET stuff. Need to emulate this for pcap
  8273.                 if filter:
  8274.                     filter = "(ether proto %i) and (%s)" % (type,filter)
  8275.                 else:
  8276.                     filter = "ether proto %i" % type
  8277.         if filter:
  8278.             self.ins.setfilter(filter, 0, 0)
  8279.         self.outs = dnet.eth(iface)
  8280.     def recv(self,x):
  8281.         ll = self.ins.datalink()
  8282.         if LLTypes.has_key(ll):
  8283.             cls = LLTypes[ll]
  8284.         else:
  8285.             warning("Unable to guess datalink type (interface=%s linktype=%i). Using Ethernet" % (self.iface, ll))
  8286.             cls = Ether
  8287.  
  8288.         pkt = self.ins.next()
  8289.         if pkt is not None:
  8290.             pkt = pkt[1]        
  8291.         if pkt is None:
  8292.             return
  8293.         
  8294.         try:
  8295.             pkt = cls(pkt)
  8296.         except:
  8297.             if conf.debug_dissector:
  8298.                 raise
  8299.             pkt = Raw(pkt)
  8300.         return pkt
  8301.  
  8302.     def nonblock_recv(self):
  8303.         self.ins.setnonblock(1)
  8304.         p = self.recv(MTU)
  8305.         self.ins.setnonblock(0)
  8306.         return p
  8307.  
  8308.     def close(self):
  8309.         if hasattr(self, "ins"):
  8310.             del(self.ins)
  8311.         if hasattr(self, "outs"):
  8312.             del(self.outs)
  8313.     
  8314.     
  8315.     
  8316.  
  8317.  
  8318. class L2pcapListenSocket(SuperSocket):
  8319.     def __init__(self, iface = None, type = ETH_P_ALL, promisc=None, filter=None):
  8320.         self.type = type
  8321.         self.outs = None
  8322.         self.ins = pcap.pcapObject()
  8323.         self.iface = iface
  8324.         if iface is None:
  8325.             iface = conf.iface
  8326.         if promisc is None:
  8327.             promisc = conf.sniff_promisc
  8328.         self.promisc = promisc
  8329.         self.ins.open_live(iface, 1600, self.promisc, 100)
  8330.         try:
  8331.             ioctl(self.ins.fileno(),BIOCIMMEDIATE,struct.pack("I",1))
  8332.         except:
  8333.             pass
  8334.         if type == ETH_P_ALL: # Do not apply any filter if Ethernet type is given
  8335.             if conf.except_filter:
  8336.                 if filter:
  8337.                     filter = "(%s) and not (%s)" % (filter, conf.except_filter)
  8338.                 else:
  8339.                     filter = "not (%s)" % conf.except_filter
  8340.             if filter:
  8341.                 self.ins.setfilter(filter, 0, 0)
  8342.  
  8343.     def close(self):
  8344.         del(self.ins)
  8345.         
  8346.     def recv(self, x):
  8347.         ll = self.ins.datalink()
  8348.         if LLTypes.has_key(ll):
  8349.             cls = LLTypes[ll]
  8350.         else:
  8351.             warning("Unable to guess datalink type (interface=%s linktype=%i). Using Ethernet" % (self.iface, ll))
  8352.             cls = Ether
  8353.  
  8354.         pkt = None
  8355.         while pkt is None:
  8356.             pkt = self.ins.next()
  8357.             if pkt is not None:
  8358.                 pkt = pkt[1]
  8359.         
  8360.         try:
  8361.             pkt = cls(pkt)
  8362.         except:
  8363.             if conf.debug_dissector:
  8364.                 raise
  8365.             pkt = Raw(pkt)
  8366.         return pkt
  8367.  
  8368.     def send(self, x):
  8369.         raise Exception("Can't send anything with L2pcapListenSocket")
  8370.  
  8371.  
  8372. class SimpleSocket(SuperSocket):
  8373.     def __init__(self, sock):
  8374.         self.ins = sock
  8375.         self.outs = sock
  8376.  
  8377.  
  8378. class StreamSocket(SimpleSocket):
  8379.     def __init__(self, sock, basecls=Raw):
  8380.         SimpleSocket.__init__(self, sock)
  8381.         self.basecls = basecls
  8382.         
  8383.     def recv(self, x=MTU):
  8384.         pkt = self.ins.recv(x, socket.MSG_PEEK)
  8385.         x = len(pkt)
  8386.         pkt = self.basecls(pkt)
  8387.         pad = pkt[Padding]
  8388.         if pad is not None and pad.underlayer is not None:
  8389.             del(pad.underlayer.payload)
  8390.         while pad is not None and not isinstance(pad, NoPayload):
  8391.             x -= len(pad.load)
  8392.             pad = pad.payload
  8393.         self.ins.recv(x)
  8394.         return pkt
  8395.         
  8396.         
  8397. class BluetoothL2CAPSocket(SuperSocket):
  8398.     def __init__(self, peer):
  8399.         s = socket.socket(socket.AF_BLUETOOTH, socket.SOCK_RAW,
  8400.                           socket.BTPROTO_L2CAP)
  8401.         s.connect((peer,0))
  8402.         
  8403.         self.ins = self.outs = s
  8404.  
  8405.     def recv(self, x):
  8406.         return L2CAP_HdrCmd(self.ins.recv(x))
  8407.     
  8408.  
  8409. class BluetoothHCISocket(SuperSocket):
  8410.     def __init__(self, iface=0x10000, type=None):
  8411.         s = socket.socket(socket.AF_BLUETOOTH, socket.SOCK_RAW, socket.BTPROTO_HCI)
  8412.         s.setsockopt(socket.SOL_HCI, socket.HCI_DATA_DIR,1)
  8413.         s.setsockopt(socket.SOL_HCI, socket.HCI_TIME_STAMP,1)
  8414.         s.setsockopt(socket.SOL_HCI, socket.HCI_FILTER, struct.pack("IIIh2x", 0xffffffffL,0xffffffffL,0xffffffffL,0)) #type mask, event mask, event mask, opcode
  8415.         s.bind((iface,))
  8416.         self.ins = self.outs = s
  8417. #        s.connect((peer,0))
  8418.         
  8419.  
  8420.     def recv(self, x):
  8421.         return HCI_Hdr(self.ins.recv(x))
  8422.     
  8423.  
  8424.  
  8425. ####################
  8426. ## Send / Receive ##
  8427. ####################
  8428.  
  8429.  
  8430.  
  8431.  
  8432. def sndrcv(pks, pkt, timeout = 2, inter = 0, verbose=None, chainCC=0, retry=0, multi=0):
  8433.     if not isinstance(pkt, Gen):
  8434.         pkt = SetGen(pkt)
  8435.         
  8436.     if verbose is None:
  8437.         verbose = conf.verb
  8438.     debug.recv = PacketList([],"Unanswered")
  8439.     debug.sent = PacketList([],"Sent")
  8440.     debug.match = SndRcvList([])
  8441.     nbrecv=0
  8442.     ans = []
  8443.     # do it here to fix random fields, so that parent and child have the same
  8444.     tobesent = [p for p in pkt]
  8445.     notans = len(tobesent)
  8446.  
  8447.     hsent={}
  8448.     for i in tobesent:
  8449.         h = i.hashret()
  8450.         if h in hsent:
  8451.             hsent[h].append(i)
  8452.         else:
  8453.             hsent[h] = [i]
  8454.     if retry < 0:
  8455.         retry = -retry
  8456.         autostop=retry
  8457.     else:
  8458.         autostop=0
  8459.  
  8460.  
  8461.     while retry >= 0:
  8462.         found=0
  8463.     
  8464.         if timeout < 0:
  8465.             timeout = None
  8466.             
  8467.         rdpipe,wrpipe = os.pipe()
  8468.         rdpipe=os.fdopen(rdpipe)
  8469.         wrpipe=os.fdopen(wrpipe,"w")
  8470.     
  8471.         pid = os.fork()
  8472.         if pid == 0:
  8473.             sys.stdin.close()
  8474.             rdpipe.close()
  8475.             try:
  8476.                 i = 0
  8477.                 if verbose:
  8478.                     print "Begin emission:"
  8479.                 for p in tobesent:
  8480.                     pks.send(p)
  8481.                     i += 1
  8482.                     time.sleep(inter)
  8483.                 if verbose:
  8484.                     print "Finished to send %i packets." % i
  8485.             except SystemExit:
  8486.                 pass
  8487.             except KeyboardInterrupt:
  8488.                 pass
  8489.             except:
  8490.                 log_runtime.exception("--- Error in child %i" % os.getpid())
  8491.                 log_runtime.info("--- Error in child %i" % os.getpid())
  8492.                 os._exit(0)
  8493.             else:
  8494.                 cPickle.dump(arp_cache, wrpipe)
  8495.                 wrpipe.close()
  8496.             os._exit(0)
  8497.         elif pid < 0:
  8498.             log_runtime.error("fork error")
  8499.         else:
  8500.             wrpipe.close()
  8501.             stoptime = 0
  8502.             remaintime = None
  8503.             inmask = [rdpipe,pks]
  8504.             try:
  8505.                 while 1:
  8506.                     if stoptime:
  8507.                         remaintime = stoptime-time.time()
  8508.                         if remaintime <= 0:
  8509.                             break
  8510.                     r = None
  8511.                     if FREEBSD or DARWIN:
  8512.                         inp, out, err = select(inmask,[],[], 0.05)
  8513.                         if len(inp) == 0 or pks in inp:
  8514.                             r = pks.nonblock_recv()
  8515.                     else:
  8516.                         inp, out, err = select(inmask,[],[], remaintime)
  8517.                         if len(inp) == 0:
  8518.                             break
  8519.                         if pks in inp:
  8520.                             r = pks.recv(MTU)
  8521.                     if rdpipe in inp:
  8522.                         if timeout:
  8523.                             stoptime = time.time()+timeout
  8524.                         del(inmask[inmask.index(rdpipe)])
  8525.                     if r is None:
  8526.                         continue
  8527.                     ok = 0
  8528.                     h = r.hashret()
  8529.                     if h in hsent:
  8530.                         hlst = hsent[h]
  8531.                         for i in range(len(hlst)):
  8532.                             if r.answers(hlst[i]):
  8533.                                 ans.append((hlst[i],r))
  8534.                                 if verbose > 1:
  8535.                                     os.write(1, "*")
  8536.                                 ok = 1                                
  8537.                                 if not multi:
  8538.                                     del(hlst[i])
  8539.                                     notans -= 1;
  8540.                                 else:
  8541.                                     if not hasattr(hlst[i], '_answered'):
  8542.                                         notans -= 1;
  8543.                                     hlst[i]._answered = 1;
  8544.                                 break
  8545.                     if notans == 0 and not multi:
  8546.                         break
  8547.                     if not ok:
  8548.                         if verbose > 1:
  8549.                             os.write(1, ".")
  8550.                         nbrecv += 1
  8551.                         if conf.debug_match:
  8552.                             debug.recv.append(r)
  8553.             except KeyboardInterrupt:
  8554.                 if chainCC:
  8555.                     raise KeyboardInterrupt
  8556.     
  8557.             try:
  8558.                 ac = cPickle.load(rdpipe)
  8559.             except EOFError:
  8560.                 warning("Child died unexpectedly. Packets may have not been sent")
  8561.             else:
  8562.                 arp_cache.update(ac)
  8563.                 os.waitpid(pid,0)
  8564.     
  8565.         remain = reduce(list.__add__, hsent.values(), [])
  8566.         if multi:
  8567.             remain = filter(lambda p: not hasattr(p, '_answered'), remain);
  8568.             
  8569.         if autostop and len(remain) > 0 and len(remain) != len(tobesent):
  8570.             retry = autostop
  8571.             
  8572.         tobesent = remain
  8573.         if len(tobesent) == 0:
  8574.             break
  8575.         retry -= 1
  8576.         
  8577.     if conf.debug_match:
  8578.         debug.sent=PacketList(remain[:],"Sent")
  8579.         debug.match=SndRcvList(ans[:])
  8580.  
  8581.     #clean the ans list to delete the field _answered
  8582.     if (multi):
  8583.         for s,r in ans:
  8584.             if hasattr(s, '_answered'):
  8585.                 del(s._answered)
  8586.     
  8587.     if verbose:
  8588.         print "\nReceived %i packets, got %i answers, remaining %i packets" % (nbrecv+len(ans), len(ans), notans)
  8589.     return SndRcvList(ans),PacketList(remain,"Unanswered"),debug.recv
  8590.  
  8591.  
  8592. def __gen_send(s, x, inter=0, loop=0, verbose=None, *args, **kargs):
  8593.     if not isinstance(x, Gen):
  8594.         x = SetGen(x)
  8595.     if verbose is None:
  8596.         verbose = conf.verb
  8597.     n = 0
  8598.     try:
  8599.         while 1:
  8600.             for p in x:
  8601.                 s.send(p)
  8602.                 n += 1
  8603.                 if verbose:
  8604.                     os.write(1,".")
  8605.                 time.sleep(inter)
  8606.             if not loop:
  8607.                 break
  8608.     except KeyboardInterrupt:
  8609.         pass
  8610.     s.close()
  8611.     if verbose:
  8612.         print "\nSent %i packets." % n
  8613.  
  8614. def send(x, inter=0, loop=0, verbose=None, *args, **kargs):
  8615.     """Send packets at layer 3
  8616. send(packets, [inter=0], [loop=0], [verbose=conf.verb]) -> None"""
  8617.     __gen_send(conf.L3socket(*args, **kargs), x, inter=inter, loop=loop, verbose=verbose)
  8618.  
  8619. def sendp(x, inter=0, loop=0, iface=None, iface_hint=None, verbose=None, *args, **kargs):
  8620.     """Send packets at layer 2
  8621. send(packets, [inter=0], [loop=0], [verbose=conf.verb]) -> None"""
  8622.     if iface is None and iface_hint is not None:
  8623.         iface = conf.route.route(iface_hint)[0]
  8624.     __gen_send(conf.L2socket(iface=iface, *args, **kargs), x, inter=inter, loop=loop, verbose=verbose)
  8625.     
  8626. def sr(x,filter=None, iface=None, *args,**kargs):
  8627.     """Send and receive packets at layer 3
  8628. nofilter: put 1 to avoid use of bpf filters
  8629. retry:    if positive, how many times to resend unanswered packets
  8630.           if negative, how many times to retry when no more packets are answered
  8631. timeout:  how much time to wait after the last packet has been sent
  8632. verbose:  set verbosity level
  8633. multi:    whether to accept multiple answers for the same stimulus
  8634. filter:   provide a BPF filter
  8635. iface:    listen answers only on the given interface"""
  8636.     if not kargs.has_key("timeout"):
  8637.         kargs["timeout"] = -1
  8638.     s = conf.L3socket(filter=filter, iface=iface)
  8639.     a,b,c=sndrcv(s,x,*args,**kargs)
  8640.     s.close()
  8641.     return a,b
  8642.  
  8643. def sr1(x,filter=None,iface=None, nofilter=0, *args,**kargs):
  8644.     """Send packets at layer 3 and return only the first answer
  8645. nofilter: put 1 to avoid use of bpf filters
  8646. retry:    if positive, how many times to resend unanswered packets
  8647.           if negative, how many times to retry when no more packets are answered
  8648. timeout:  how much time to wait after the last packet has been sent
  8649. verbose:  set verbosity level
  8650. multi:    whether to accept multiple answers for the same stimulus
  8651. filter:   provide a BPF filter
  8652. iface:    listen answers only on the given interface"""
  8653.     if not kargs.has_key("timeout"):
  8654.         kargs["timeout"] = -1
  8655.     s=conf.L3socket(filter=filter, nofilter=nofilter, iface=iface)
  8656.     a,b,c=sndrcv(s,x,*args,**kargs)
  8657.     s.close()
  8658.     if len(a) > 0:
  8659.         return a[0][1]
  8660.     else:
  8661.         return None
  8662.  
  8663. def srp(x,iface=None, iface_hint=None, filter=None, nofilter=0, type=ETH_P_ALL, *args,**kargs):
  8664.     """Send and receive packets at layer 2
  8665. nofilter: put 1 to avoid use of bpf filters
  8666. retry:    if positive, how many times to resend unanswered packets
  8667.           if negative, how many times to retry when no more packets are answered
  8668. timeout:  how much time to wait after the last packet has been sent
  8669. verbose:  set verbosity level
  8670. multi:    whether to accept multiple answers for the same stimulus
  8671. filter:   provide a BPF filter
  8672. iface:    work only on the given interface"""
  8673.     if not kargs.has_key("timeout"):
  8674.         kargs["timeout"] = -1
  8675.     if iface is None and iface_hint is not None:
  8676.         iface = conf.route.route(iface_hint)[0]
  8677.     a,b,c=sndrcv(conf.L2socket(iface=iface, filter=filter, nofilter=nofilter, type=type),x,*args,**kargs)
  8678.     return a,b
  8679.  
  8680. def srp1(*args,**kargs):
  8681.     """Send and receive packets at layer 2 and return only the first answer
  8682. nofilter: put 1 to avoid use of bpf filters
  8683. retry:    if positive, how many times to resend unanswered packets
  8684.           if negative, how many times to retry when no more packets are answered
  8685. timeout:  how much time to wait after the last packet has been sent
  8686. verbose:  set verbosity level
  8687. multi:    whether to accept multiple answers for the same stimulus
  8688. filter:   provide a BPF filter
  8689. iface:    work only on the given interface"""
  8690.     if not kargs.has_key("timeout"):
  8691.         kargs["timeout"] = -1
  8692.     a,b=srp(*args,**kargs)
  8693.     if len(a) > 0:
  8694.         return a[0][1]
  8695.     else:
  8696.         return None
  8697.  
  8698. def __sr_loop(srfunc, pkts, prn=lambda x:x[1].summary(), prnfail=lambda x:x.summary(), inter=1, timeout=0, count=None, verbose=0,  *args, **kargs):
  8699.     n = 0
  8700.     r = 0
  8701.     ct = conf.color_theme
  8702.     parity = 0
  8703.     if timeout == 0:
  8704.         timeout = min(2*inter, 5)
  8705.     try:
  8706.         while 1:
  8707.             parity ^= 1
  8708.             col = [ct.even,ct.odd][parity]
  8709.             if count is not None:
  8710.                 if count == 0:
  8711.                     break
  8712.                 count -= 1
  8713.             start = time.time()
  8714.             print "\rsend...\r",
  8715.             res = srfunc(pkts, timeout=timeout, verbose=0, chainCC=1, *args, **kargs)
  8716.             n += len(res[0])+len(res[1])
  8717.             r += len(res[0])
  8718.             if prn and len(res[0]) > 0:
  8719.                 msg = "RECV %i:" % len(res[0])
  8720.                 print  "\r"+ct.success(msg),
  8721.                 for p in res[0]:
  8722.                     print col(prn(p))
  8723.                     print " "*len(msg),
  8724.             if prnfail and len(res[1]) > 0:
  8725.                 msg = "fail %i:" % len(res[1])
  8726.                 print "\r"+ct.fail(msg),
  8727.                 for p in res[1]:
  8728.                     print col(prnfail(p))
  8729.                     print " "*len(msg),
  8730.             if not (prn or prnfail):
  8731.                 print "recv:%i  fail:%i" % tuple(map(len, res[:2]))
  8732.             end=time.time()
  8733.             if end-start < inter:
  8734.                 time.sleep(inter+start-end)
  8735.     except KeyboardInterrupt:
  8736.         pass
  8737.  
  8738.     if n>0:
  8739.         print "%s\nSent %i packets, received %i packets. %3.1f%% hits." % (Color.normal,n,r,100.0*r/n)
  8740.  
  8741. def srloop(pkts, *args, **kargs):
  8742.     """Send a packet at layer 3 in loop and print the answer each time
  8743. srloop(pkts, [prn], [inter], [count], ...) --> None"""
  8744.     __sr_loop(sr, pkts, *args, **kargs)
  8745.  
  8746. def srploop(pkts, *args, **kargs):
  8747.     """Send a packet at layer 2 in loop and print the answer each time
  8748. srloop(pkts, [prn], [inter], [count], ...) --> None"""
  8749.     __sr_loop(srp, pkts, *args, **kargs)
  8750.  
  8751.            
  8752. ## Bluetooth
  8753.  
  8754.  
  8755. def srbt(peer, pkts, inter=0.1, *args, **kargs):
  8756.     s = conf.BTsocket(peer=peer)
  8757.     a,b,c=sndrcv(s,pkts,inter=inter,*args,**kargs)
  8758.     s.close()
  8759.     return a,b
  8760.  
  8761. def srbt1(peer, pkts, *args, **kargs):
  8762.     a,b = srbt(peer, pkts, *args, **kargs)
  8763.     if len(a) > 0:
  8764.         return a[0][1]
  8765.         
  8766.     
  8767.  
  8768.  
  8769.  
  8770. #############################
  8771. ## pcap capture file stuff ##
  8772. #############################
  8773.  
  8774. def wrpcap(filename, pkt, *args, **kargs):
  8775.     """Write a list of packets to a pcap file
  8776. linktype: force linktype value
  8777. endianness: "<" or ">", force endianness"""
  8778.     PcapWriter(filename, *args, **kargs).write(pkt)
  8779.  
  8780. def rdpcap(filename, count=-1):
  8781.     """Read a pcap file and return a packet list
  8782. count: read only <count> packets"""
  8783.     return PcapReader(filename).read_all(count=count)
  8784.  
  8785. class PcapReader:
  8786.     """A stateful pcap reader
  8787.     
  8788.     Based entirely on scapy.rdpcap(), this class allows for packets
  8789.     to be dispatched without having to be loaded into memory all at
  8790.     once
  8791.     """
  8792.  
  8793.     def __init__(self, filename):
  8794.         self.filename = filename
  8795.         self.f = open(filename,"r")
  8796.         magic = self.f.read(4)
  8797.         if magic == "\xa1\xb2\xc3\xd4": #big endian
  8798.             self.endian = ">"
  8799.         elif  magic == "\xd4\xc3\xb2\xa1": #little endian
  8800.             self.endian = "<"
  8801.         else:
  8802.             raise RuntimeWarning, "Not a pcap capture file (bad magic)"
  8803.         hdr = self.f.read(20)
  8804.         if len(hdr)<20:
  8805.             raise RuntimeWarning, "Invalid pcap file (too short)"
  8806.         vermaj,vermin,tz,sig,snaplen,linktype = struct.unpack(self.endian+"HHIIII",hdr)
  8807.         self.LLcls = LLTypes.get(linktype, Raw)
  8808.         if self.LLcls == Raw:
  8809.             warning("PcapReader: unkonwon LL type [%i]/[%#x]. Using Raw packets" % (linktype,linktype))
  8810.  
  8811.     def __iter__(self):
  8812.         return self
  8813.  
  8814.     def next(self):
  8815.         """impliment the iterator protocol on a set of packets in a
  8816.         pcap file
  8817.         """
  8818.         pkt = self.read_packet()
  8819.         if pkt == None:
  8820.             raise StopIteration
  8821.         return pkt
  8822.  
  8823.  
  8824.     def read_packet(self):
  8825.         """return a single packet read from the file
  8826.         
  8827.         returns None when no more packets are available
  8828.         """
  8829.         hdr = self.f.read(16)
  8830.         if len(hdr) < 16:
  8831.             return None
  8832.         sec,usec,caplen,olen = struct.unpack(self.endian+"IIII", hdr)
  8833.         s = self.f.read(caplen)
  8834.         try:
  8835.             p = self.LLcls(s)
  8836.         except:
  8837.             if conf.debug_dissector:
  8838.                 raise
  8839.             p = Raw(s)
  8840.         p.time = sec+0.000001*usec
  8841.         return p
  8842.     
  8843.     def dispatch(self, callback):
  8844.         """call the specified callback routine for each packet read
  8845.         
  8846.         This is just a convienience function for the main loop
  8847.         that allows for easy launching of packet processing in a 
  8848.         thread.
  8849.         """
  8850.         p = self.read_packet()
  8851.         while p != None:
  8852.             callback(p)
  8853.             p = self.read_packet()
  8854.  
  8855.     def read_all(self,count=-1):
  8856.         """return a list of all packets in the pcap file
  8857.         """
  8858.         res=[]
  8859.         while count != 0:
  8860.             count -= 1
  8861.             p = self.read_packet()
  8862.             if p is None:
  8863.                 break
  8864.             res.append(p)
  8865.         return PacketList(res,name = os.path.basename(self.filename))
  8866.  
  8867.     def recv(self, size):
  8868.         """ Emulate a socket
  8869.         """
  8870.         return self.read_packet()
  8871.         
  8872.  
  8873.  
  8874. class PcapWriter:
  8875.     """A pcap writer with more control than wrpcap()
  8876.     
  8877.     This routine is based entirely on scapy.wrpcap(), but adds capability
  8878.     of writing one packet at a time in a streaming manner.
  8879.     """
  8880.     def __init__(self, filename, linktype=None, endianness=""):
  8881.         self.linktype = linktype
  8882.         self.header_done = 0
  8883.         self.f = open(filename,"w")
  8884.         self.endian = endianness
  8885.  
  8886.  
  8887.     def write(self, pkt):
  8888.         """accepts a either a single packet or a list of packets
  8889.         to be written to the dumpfile
  8890.         """
  8891.         
  8892.         if self.header_done == 0:
  8893.             if self.linktype == None:
  8894.                 if isinstance(pkt,Packet):
  8895.                     linktype = LLNumTypes.get(pkt.__class__,1)
  8896.                 else:
  8897.                     linktype = LLNumTypes.get(pkt[0].__class__,1)
  8898.  
  8899.             self.f.write(struct.pack(self.endian+"IHHIIII", 0xa1b2c3d4L,
  8900.                                      2, 4, 0, 0, MTU, linktype))
  8901.             self.header_done = 1
  8902.  
  8903.         for p in pkt:
  8904.             self._write_packet(p)
  8905.  
  8906.     def _write_packet(self, packet):
  8907.         """writes a single packet to the pcap file
  8908.         """
  8909.         s = str(packet)
  8910.         l = len(s)
  8911.         sec = int(packet.time)
  8912.         usec = int((packet.time-sec)*1000000)
  8913.         self.f.write(struct.pack(self.endian+"IIII", sec, usec, l, l))
  8914.         self.f.write(s)
  8915.  
  8916.  
  8917. def import_hexcap():
  8918.     p = ""
  8919.     try:
  8920.         while 1:
  8921.             l = raw_input()
  8922.             l = l.strip()
  8923.             l = l[l.find("  "):]
  8924.             l = l.strip()
  8925.             l = l[:40]
  8926.             l = l.replace(" ","")
  8927.             p += l
  8928.     except EOFError:
  8929.         pass
  8930.     p2=""
  8931.     for i in range(len(p)/2):
  8932.         p2 += chr(int(p[2*i:2*i+2],16))
  8933.     return p2
  8934.         
  8935.  
  8936.  
  8937.  
  8938. #####################
  8939. ## knowledge bases ##
  8940. #####################
  8941.  
  8942. class KnowledgeBase:
  8943.     def __init__(self, filename):
  8944.         self.filename = filename
  8945.         self.base = None
  8946.  
  8947.     def lazy_init(self):
  8948.         self.base = ""
  8949.  
  8950.     def reload(self, filename = None):
  8951.         if filename is not None:
  8952.             self.filename = filename
  8953.         oldbase = self.base
  8954.         self.base = None
  8955.         self.lazy_init()
  8956.         if self.base is None:
  8957.             self.base = oldbase
  8958.  
  8959.     def get_base(self):
  8960.         if self.base is None:
  8961.             self.lazy_init()
  8962.         return self.base
  8963.     
  8964.  
  8965.  
  8966. ##########################
  8967. ## IP location database ##
  8968. ##########################
  8969.  
  8970. class IPCountryKnowledgeBase(KnowledgeBase):
  8971.     """
  8972. How to generate the base :
  8973. db = []
  8974. for l in open("GeoIPCountryWhois.csv").readlines():
  8975.     s,e,c = l.split(",")[2:5]
  8976.     db.append((int(s[1:-1]),int(e[1:-1]),c[1:-1]))
  8977. cPickle.dump(gzip.open("xxx","w"),db)
  8978. """
  8979.     def lazy_init(self):
  8980.         self.base = load_object(self.filename)
  8981.  
  8982.  
  8983. class CountryLocKnowledgeBase(KnowledgeBase):
  8984.     def lazy_init(self):
  8985.         f=open(self.filename)
  8986.         self.base = {}
  8987.         while 1:
  8988.             l = f.readline()
  8989.             if not l:
  8990.                 break
  8991.             l = l.strip().split(",")
  8992.             if len(l) != 3:
  8993.                 continue
  8994.             c,lat,long = l
  8995.             
  8996.             self.base[c] = (float(long),float(lat))
  8997.         f.close()
  8998.             
  8999.         
  9000.  
  9001.  
  9002. def locate_ip(ip):
  9003.     ip=map(int,ip.split("."))
  9004.     ip = ip[3]+(ip[2]<<8L)+(ip[1]<<16L)+(ip[0]<<24L)
  9005.  
  9006.     cloc = country_loc_kdb.get_base()
  9007.     db = IP_country_kdb.get_base()
  9008.  
  9009.     d=0
  9010.     f=len(db)-1
  9011.     while (f-d) > 1:
  9012.         guess = (d+f)/2
  9013.         if ip > db[guess][0]:
  9014.             d = guess
  9015.         else:
  9016.             f = guess
  9017.     s,e,c = db[guess]
  9018.     if  s <= ip and ip <= e:
  9019.         return cloc.get(c,None)
  9020.  
  9021.  
  9022.     
  9023.  
  9024. ###############
  9025. ## p0f stuff ##
  9026. ###############
  9027.  
  9028. # File format:
  9029. #
  9030. # wwww:ttt:mmm:D:W:S:N:I:OS Description
  9031. #
  9032. # wwww - window size
  9033. # ttt  - time to live
  9034. # mmm  - maximum segment size
  9035. # D    - don't fragment flag  (0=unset, 1=set) 
  9036. # W    - window scaling (-1=not present, other=value)
  9037. # S    - sackOK flag (0=unset, 1=set)
  9038. # N    - nop flag (0=unset, 1=set)
  9039. # I    - packet size (-1 = irrevelant)
  9040.  
  9041.  
  9042.  
  9043. class p0fKnowledgeBase(KnowledgeBase):
  9044.     def __init__(self, filename):
  9045.         KnowledgeBase.__init__(self, filename)
  9046.         self.ttl_range=[255]
  9047.     def lazy_init(self):
  9048.         try:
  9049.             f=open(self.filename)
  9050.         except IOError:
  9051.             warning("Can't open base %s" % self.filename)
  9052.             return
  9053.         try:
  9054.             self.base = []
  9055.             for l in f:
  9056.                 if l[0] in ["#","\n"]:
  9057.                     continue
  9058.                 l = tuple(l.split(":"))
  9059.                 if len(l) < 9:
  9060.                     continue
  9061.                 li = map(int,l[:8])
  9062.                 if li[1] not in self.ttl_range:
  9063.                     self.ttl_range.append(li[1])
  9064.                     self.ttl_range.sort()
  9065.                 self.base.append((li,":".join(l[8:])[:-1]))
  9066.         except:
  9067.             warning("Can't parse p0f database (new p0f version ?)")
  9068.             self.base = None
  9069.         f.close()
  9070.  
  9071.  
  9072. def packet2p0f(pkt):
  9073.     while pkt.haslayer(IP) and pkt.haslayer(TCP):
  9074.         pkt = pkt.getlayer(IP)
  9075.         if isinstance(pkt.payload, TCP):
  9076.             break
  9077.         pkt = pkt.payload
  9078.  
  9079.     if not isinstance(pkt, IP) or not isinstance(pkt.payload, TCP):
  9080.         raise TypeError("Not a TCP/IP packet")
  9081.     if pkt.payload.flags & 0x13 != 0x02: #S,!A,!F
  9082.         raise TypeError("Not a syn packet")
  9083.  
  9084.     if "MSS" in pkt.payload.options:
  9085.         mss = pkt.payload.options["MSS"]
  9086.     else:
  9087.         mss = -1
  9088.     if "WScale" in pkt.payload.options:
  9089.         wscale = pkt.payload.options["WScale"]
  9090.     else:
  9091.         wscale = -1
  9092.     t = p0f_kdb.ttl_range[:]
  9093.     t += [pkt.ttl]
  9094.     t.sort()
  9095.     ttl=t[t.index(pkt.ttl)+1]
  9096.         
  9097.     return (pkt.payload.window,
  9098.             ttl,
  9099.             mss,
  9100.             pkt.flags & 0x2 != 0,
  9101.             wscale,
  9102.             "SAckOK" in pkt.payload.options,
  9103.             "NOP" in pkt.payload.options,
  9104.             pkt.len)
  9105.  
  9106. def p0f_dist(x,y):
  9107.     d = 0
  9108.     for i in range(len(x)):
  9109.         if x[i] != y[i]:
  9110.             d += 1
  9111.     if x[-1] == -1 ^ y[-1] == -1: # packet len was irrelevant
  9112.         d -= 1
  9113.     return d
  9114.     
  9115.  
  9116. def p0f(pkt):
  9117.     """Passive OS fingerprinting: which OS emitted this TCP SYN ?
  9118. p0f(packet) -> accuracy, [list of guesses]
  9119. """
  9120.     pb = p0f_kdb.get_base()
  9121.     if not pb:
  9122.         warning("p0f base empty.")
  9123.         return []
  9124.     s = len(pb[0][0])
  9125.     r = []
  9126.     min = s+1
  9127.     sig = packet2p0f(pkt)
  9128.     for b,name in pb:
  9129.         d = p0f_dist(sig,b)
  9130.         if d < min:
  9131.             r = []
  9132.             min = d
  9133.         if d == min:
  9134.             r.append(name)
  9135.     accurracy = ( 1.0-(1.0*min)/s )
  9136.     return accurracy,r
  9137.             
  9138.  
  9139. def prnp0f(pkt):
  9140.     try:
  9141.         print p0f(pkt)
  9142.     except:
  9143.         pass
  9144.     
  9145.  
  9146. def pkt2uptime(pkt, HZ=100):
  9147.     """Calculate the date the machine which emitted the packet booted using TCP timestamp
  9148. pkt2uptime(pkt, [HZ=100])"""
  9149.     if not isinstance(pkt, Packet):
  9150.         raise TypeError("Not a TCP packet")
  9151.     if isinstance(pkt,NoPayload):
  9152.         raise TypeError("Not a TCP packet")
  9153.     if not isinstance(pkt, TCP):
  9154.         return pkt2uptime(pkt.payload)
  9155.     if "Timestamp" not in pkt.options:
  9156.         raise TypeError("No timestamp option")
  9157.     t = pkt.options["Timestamp"][0]
  9158.     t = pkt.time-t*1.0/HZ
  9159.     return time.ctime(t)
  9160.     
  9161.  
  9162.  
  9163. #################
  9164. ## Queso stuff ##
  9165. #################
  9166.  
  9167.  
  9168. def quesoTCPflags(flags):
  9169.     if flags == "-":
  9170.         return "-"
  9171.     flv = "FSRPAUXY"
  9172.     v = 0
  9173.     for i in flags:
  9174.         v |= 2**flv.index(i)
  9175.     return "%x" % v
  9176.  
  9177. class QuesoKnowledgeBase(KnowledgeBase):
  9178.     def lazy_init(self):
  9179.         try:
  9180.             f = open(self.filename)
  9181.         except IOError:
  9182.             return
  9183.         self.base = {}
  9184.         p = None
  9185.         try:
  9186.             for l in f:
  9187.                 l = l.strip()
  9188.                 if not l or l[0] == ';':
  9189.                     continue
  9190.                 if l[0] == '*':
  9191.                     if p is not None:
  9192.                         p[""] = name
  9193.                     name = l[1:].strip()
  9194.                     p = self.base
  9195.                     continue
  9196.                 if l[0] not in list("0123456"):
  9197.                     continue
  9198.                 res = l[2:].split()
  9199.                 res[-1] = quesoTCPflags(res[-1])
  9200.                 res = " ".join(res)
  9201.                 if not p.has_key(res):
  9202.                     p[res] = {}
  9203.                 p = p[res]
  9204.             if p is not None:
  9205.                 p[""] = name
  9206.         except:
  9207.             self.base = None
  9208.             warning("Can't load queso base [%s]", self.filename)
  9209.         f.close()
  9210.             
  9211.         
  9212.  
  9213.     
  9214. def queso_sig(target, dport=80, timeout=3):
  9215.     p = queso_kdb.get_base()
  9216.     ret = []
  9217.     for flags in ["S", "SA", "F", "FA", "SF", "P", "SEC"]:
  9218.         ans, unans = sr(IP(dst=target)/TCP(dport=dport,flags=flags,seq=RandInt()),
  9219.                         timeout=timeout, verbose=0)
  9220.         if len(ans) == 0:
  9221.             rs = "- - - -"
  9222.         else:
  9223.             s,r = ans[0]
  9224.             rs = "%i" % (r.seq != 0)
  9225.             if not r.ack:
  9226.                 r += " 0"
  9227.             elif r.ack-s.seq > 666:
  9228.                 rs += " R" % 0
  9229.             else:
  9230.                 rs += " +%i" % (r.ack-s.seq)
  9231.             rs += " %X" % r.window
  9232.             rs += " %x" % r.payload.flags
  9233.         ret.append(rs)
  9234.     return ret
  9235.             
  9236. def queso_search(sig):
  9237.     p = queso_kdb.get_base()
  9238.     sig.reverse()
  9239.     ret = []
  9240.     try:
  9241.         while sig:
  9242.             s = sig.pop()
  9243.             p = p[s]
  9244.             if p.has_key(""):
  9245.                 ret.append(p[""])
  9246.     except KeyError:
  9247.         pass
  9248.     return ret
  9249.         
  9250.  
  9251. def queso(*args,**kargs):
  9252.     """Queso OS fingerprinting
  9253. queso(target, dport=80, timeout=3)"""
  9254.     return queso_search(queso_sig(*args, **kargs))
  9255.  
  9256.  
  9257.  
  9258. ######################
  9259. ## nmap OS fp stuff ##
  9260. ######################
  9261.  
  9262.  
  9263. class NmapKnowledgeBase(KnowledgeBase):
  9264.     def lazy_init(self):
  9265.         try:
  9266.             f=open(self.filename)
  9267.         except IOError:
  9268.             return
  9269.  
  9270.         self.base = []
  9271.         name = None
  9272.         try:
  9273.             for l in f:
  9274.                 l = l.strip()
  9275.                 if not l or l[0] == "#":
  9276.                     continue
  9277.                 if l[:12] == "Fingerprint ":
  9278.                     if name is not None:
  9279.                         self.base.append((name,sig))
  9280.                     name = l[12:].strip()
  9281.                     sig={}
  9282.                     p = self.base
  9283.                     continue
  9284.                 elif l[:6] == "Class ":
  9285.                     continue
  9286.                 op = l.find("(")
  9287.                 cl = l.find(")")
  9288.                 if op < 0 or cl < 0:
  9289.                     warning("error reading nmap os fp base file")
  9290.                     continue
  9291.                 test = l[:op]
  9292.                 s = map(lambda x: x.split("="), l[op+1:cl].split("%"))
  9293.                 si = {}
  9294.                 for n,v in s:
  9295.                     si[n] = v
  9296.                 sig[test]=si
  9297.             if name is not None:
  9298.                 self.base.append((name,sig))
  9299.         except:
  9300.             self.base = None
  9301.             warning("Can't read nmap database [%s](new nmap version ?)" % self.filename)
  9302.         f.close()
  9303.         
  9304. def TCPflags2str(f):
  9305.     fl="FSRPAUEC"
  9306.     s=""
  9307.     for i in range(len(fl)):
  9308.         if f & 1:
  9309.             s = fl[i]+s
  9310.         f >>= 1
  9311.     return s
  9312.  
  9313. def nmap_tcppacket_sig(pkt):
  9314.     r = {}
  9315.     if pkt is not None:
  9316. #        r["Resp"] = "Y"
  9317.         r["DF"] = (pkt.flags & 2) and "Y" or "N"
  9318.         r["W"] = "%X" % pkt.window
  9319.         r["ACK"] = pkt.ack==2 and "S++" or pkt.ack==1 and "S" or "O"
  9320.         r["Flags"] = TCPflags2str(pkt.payload.flags)
  9321.         r["Ops"] = "".join(map(lambda x: x[0][0],pkt.payload.options))
  9322.     else:
  9323.         r["Resp"] = "N"
  9324.     return r
  9325.  
  9326.  
  9327. def nmap_udppacket_sig(S,T):
  9328.     r={}
  9329.     if T is None:
  9330.         r["Resp"] = "N"
  9331.     else:
  9332.         r["DF"] = (T.flags & 2) and "Y" or "N"
  9333.         r["TOS"] = "%X" % T.tos
  9334.         r["IPLEN"] = "%X" % T.len
  9335.         r["RIPTL"] = "%X" % T.payload.payload.len
  9336.         r["RID"] = S.id == T.payload.payload.id and "E" or "F"
  9337.         r["RIPCK"] = S.chksum == T.getlayer(IPerror).chksum and "E" or T.getlayer(IPerror).chksum == 0 and "0" or "F"
  9338.         r["UCK"] = S.payload.chksum == T.getlayer(UDPerror).chksum and "E" or T.getlayer(UDPerror).chksum ==0 and "0" or "F"
  9339.         r["ULEN"] = "%X" % T.getlayer(UDPerror).len
  9340.         r["DAT"] = T.getlayer(Raw) is None and "E" or S.getlayer(Raw).load == T.getlayer(Raw).load and "E" or "F"
  9341.     return r
  9342.     
  9343.  
  9344.  
  9345. def nmap_match_one_sig(seen, ref):
  9346.     c = 0
  9347.     for k in seen.keys():
  9348.         if ref.has_key(k):
  9349.             if seen[k] in ref[k].split("|"):
  9350.                 c += 1
  9351.     if c == 0 and seen.get("Resp") == "N":
  9352.         return 0.7
  9353.     else:
  9354.         return 1.0*c/len(seen.keys())
  9355.         
  9356.         
  9357.  
  9358. def nmap_sig(target, oport=80, cport=81, ucport=1):
  9359.     res = {}
  9360.  
  9361.     tcpopt = [ ("WScale", 10),
  9362.                ("NOP",None),
  9363.                ("MSS", 256),
  9364.                ("Timestamp",(123,0)) ]
  9365.     tests = [ IP(dst=target, id=1)/TCP(seq=1, sport=5001, dport=oport, options=tcpopt, flags="CS"),
  9366.               IP(dst=target, id=1)/TCP(seq=1, sport=5002, dport=oport, options=tcpopt, flags=0),
  9367.               IP(dst=target, id=1)/TCP(seq=1, sport=5003, dport=oport, options=tcpopt, flags="SFUP"),
  9368.               IP(dst=target, id=1)/TCP(seq=1, sport=5004, dport=oport, options=tcpopt, flags="A"),
  9369.               IP(dst=target, id=1)/TCP(seq=1, sport=5005, dport=cport, options=tcpopt, flags="S"),
  9370.               IP(dst=target, id=1)/TCP(seq=1, sport=5006, dport=cport, options=tcpopt, flags="A"),
  9371.               IP(dst=target, id=1)/TCP(seq=1, sport=5007, dport=cport, options=tcpopt, flags="FPU"),
  9372.               IP(str(IP(dst=target)/UDP(sport=5008,dport=ucport)/(300*"i"))) ]
  9373.  
  9374.     ans, unans = sr(tests, timeout=2)
  9375.     ans += map(lambda x: (x,None), unans)
  9376.  
  9377.     for S,T in ans:
  9378.         if S.sport == 5008:
  9379.             res["PU"] = nmap_udppacket_sig(S,T)
  9380.         else:
  9381.             t = "T%i" % (S.sport-5000)
  9382.             if T is not None and T.haslayer(ICMP):
  9383.                 warning("Test %s answered by an ICMP" % t)
  9384.                 T=None
  9385.             res[t] = nmap_tcppacket_sig(T)
  9386.  
  9387.     return res
  9388.  
  9389. def nmap_probes2sig(tests):
  9390.     tests=tests.copy()
  9391.     res = {}
  9392.     if "PU" in tests:
  9393.         res["PU"] = nmap_udppacket_sig(*tests["PU"])
  9394.         del(tests["PU"])
  9395.     for k in tests:
  9396.         res[k] = nmap_tcppacket_sig(tests[k])
  9397.     return res
  9398.         
  9399.  
  9400. def nmap_search(sigs):
  9401.     guess = 0,[]
  9402.     for os,fp in nmap_kdb.get_base():
  9403.         c = 0.0
  9404.         for t in sigs.keys():
  9405.             if t in fp:
  9406.                 c += nmap_match_one_sig(sigs[t], fp[t])
  9407.         c /= len(sigs.keys())
  9408.         if c > guess[0]:
  9409.             guess = c,[ os ]
  9410.         elif c == guess[0]:
  9411.             guess[1].append(os)
  9412.     return guess
  9413.     
  9414.     
  9415. def nmap_fp(target, oport=80, cport=81):
  9416.     """nmap fingerprinting
  9417. nmap_fp(target, [oport=80,] [cport=81,]) -> list of best guesses with accuracy
  9418. """
  9419.     sigs = nmap_sig(target, oport, cport)
  9420.     return nmap_search(sigs)
  9421.         
  9422.  
  9423. def nmap_sig2txt(sig):
  9424.     torder = ["TSeq","T1","T2","T3","T4","T5","T6","T7","PU"]
  9425.     korder = ["Class", "gcd", "SI", "IPID", "TS",
  9426.               "Resp", "DF", "W", "ACK", "Flags", "Ops",
  9427.               "TOS", "IPLEN", "RIPTL", "RID", "RIPCK", "UCK", "ULEN", "DAT" ]
  9428.     txt=[]
  9429.     for i in sig.keys():
  9430.         if i not in torder:
  9431.             torder.append(i)
  9432.     for t in torder:
  9433.         sl = sig.get(t)
  9434.         if sl is None:
  9435.             continue
  9436.         s = []
  9437.         for k in korder:
  9438.             v = sl.get(k)
  9439.             if v is None:
  9440.                 continue
  9441.             s.append("%s=%s"%(k,v))
  9442.         txt.append("%s(%s)" % (t, "%".join(s)))
  9443.     return "\n".join(txt)
  9444.             
  9445.         
  9446.  
  9447.  
  9448.  
  9449. ###################
  9450. ## User commands ##
  9451. ###################
  9452.  
  9453.  
  9454. def sniff(count=0, store=1, offline=None, prn = None, lfilter=None, L2socket=None, timeout=None, *arg, **karg):
  9455.     """Sniff packets
  9456. sniff([count=0,] [prn=None,] [store=1,] [offline=None,] [lfilter=None,] + L2ListenSocket args) -> list of packets
  9457.  
  9458.   count: number of packets to capture. 0 means infinity
  9459.   store: wether to store sniffed packets or discard them
  9460.     prn: function to apply to each packet. If something is returned,
  9461.          it is displayed. Ex:
  9462.          ex: prn = lambda x: x.summary()
  9463. lfilter: python function applied to each packet to determine
  9464.          if further action may be done
  9465.          ex: lfilter = lambda x: x.haslayer(Padding)
  9466. offline: pcap file to read packets from, instead of sniffing them
  9467. timeout: stop sniffing after a given time (default: None)
  9468. L2socket: use the provided L2socket
  9469.     """
  9470.     c = 0
  9471.  
  9472.     if offline is None:
  9473.         if L2socket is None:
  9474.             L2socket = conf.L2listen
  9475.         s = L2socket(type=ETH_P_ALL, *arg, **karg)
  9476.     else:
  9477.         s = PcapReader(offline)
  9478.  
  9479.     lst = []
  9480.     if timeout is not None:
  9481.         stoptime = time.time()+timeout
  9482.     remain = None
  9483.     while 1:
  9484.         try:
  9485.             if timeout is not None:
  9486.                 remain = stoptime-time.time()
  9487.                 if remain <= 0:
  9488.                     break
  9489.             sel = select([s],[],[],remain)
  9490.             if s in sel[0]:
  9491.                 p = s.recv(MTU)
  9492.                 if p is None:
  9493.                     break
  9494.                 if lfilter and not lfilter(p):
  9495.                     continue
  9496.                 if store:
  9497.                     lst.append(p)
  9498.                 c += 1
  9499.                 if prn:
  9500.                     r = prn(p)
  9501.                     if r is not None:
  9502.                         print r
  9503.                 if count > 0 and c >= count:
  9504.                     break
  9505.         except KeyboardInterrupt:
  9506.             break
  9507.     return PacketList(lst,"Sniffed")
  9508.  
  9509.  
  9510.  
  9511. def arpcachepoison(target, victim, interval=60):
  9512.     """Poison target's cache with (your MAC,victim's IP) couple
  9513. arpcachepoison(target, victim, [interval=60]) -> None
  9514. """
  9515.     tmac = getmacbyip(target)
  9516.     p = Ether(dst=tmac)/ARP(op="who-has", psrc=victim, pdst=target)
  9517.     try:
  9518.         while 1:
  9519.             sendp(p, iface_hint=target)
  9520.             if conf.verb > 1:
  9521.                 os.write(1,".")
  9522.             time.sleep(interval)
  9523.     except KeyboardInterrupt:
  9524.         pass
  9525.  
  9526. def traceroute(target, dport=80, minttl=1, maxttl=30, sport=RandShort(), l4 = None, filter=None, timeout=2, **kargs):
  9527.     """Instant TCP traceroute
  9528. traceroute(target, [maxttl=30], [dport=80], [sport=80]) -> None
  9529. """
  9530.     if filter is None:
  9531.         filter="(icmp and icmp[0]=11) or (tcp and (tcp[13] & 0x16 > 0x10))"
  9532.     if l4 is None:
  9533.         a,b = sr(IP(dst=target, id=RandShort(), ttl=(minttl,maxttl))/TCP(seq=RandInt(),sport=sport, dport=dport),
  9534.                  timeout=timeout, filter=filter, **kargs)
  9535.     else:
  9536.         a,b = sr(IP(dst=target, id=RandShort(), ttl=(minttl,maxttl))/l4,
  9537.                  timeout=timeout, **kargs)
  9538.  
  9539.     a = TracerouteResult(a.res)
  9540.     a.display()
  9541.     return a,b
  9542.  
  9543.  
  9544.  
  9545.  
  9546. def arping(net, timeout=2, **kargs):
  9547.     """Send ARP who-has requests to determine which hosts are up
  9548. arping(net, iface=conf.iface) -> None"""
  9549.     ans,unans = srp(Ether(dst="ff:ff:ff:ff:ff:ff")/ARP(pdst=net),
  9550.                     filter="arp and arp[7] = 2", timeout=timeout, iface_hint=net, **kargs)
  9551.     ans = ARPingResult(ans.res)
  9552.     ans.display()
  9553.     return ans,unans
  9554.  
  9555. def dyndns_add(nameserver, name, rdata, type="A", ttl=10):
  9556.     """Send a DNS add message to a nameserver for "name" to have a new "rdata"
  9557. dyndns_add(nameserver, name, rdata, type="A", ttl=10) -> result code (0=ok)
  9558.  
  9559. example: dyndns_add("ns1.toto.com", "dyn.toto.com", "127.0.0.1")
  9560. RFC2136
  9561. """
  9562.     zone = name[name.find(".")+1:]
  9563.     r=sr1(IP(dst=nameserver)/UDP()/DNS(opcode=5,
  9564.                                        qd=[DNSQR(qname=zone, qtype="SOA")],
  9565.                                        ns=[DNSRR(rrname=name, type="A",
  9566.                                                  ttl=ttl, rdata=rdata)]),
  9567.           verbose=0, timeout=5)
  9568.     if r and r.haslayer(DNS):
  9569.         return r.getlayer(DNS).rcode
  9570.     else:
  9571.         return -1
  9572.     
  9573.     
  9574.     
  9575.  
  9576. def dyndns_del(nameserver, name, type="ALL", ttl=10):
  9577.     """Send a DNS delete message to a nameserver for "name"
  9578. dyndns_del(nameserver, name, type="ANY", ttl=10) -> result code (0=ok)
  9579.  
  9580. example: dyndns_del("ns1.toto.com", "dyn.toto.com")
  9581. RFC2136
  9582. """
  9583.     zone = name[name.find(".")+1:]
  9584.     r=sr1(IP(dst=nameserver)/UDP()/DNS(opcode=5,
  9585.                                        qd=[DNSQR(qname=zone, qtype="SOA")],
  9586.                                        ns=[DNSRR(rrname=name, type=type,
  9587.                                                  rclass="ANY", ttl=0, rdata="")]),
  9588.           verbose=0, timeout=5)
  9589.     if r and r.haslayer(DNS):
  9590.         return r.getlayer(DNS).rcode
  9591.     else:
  9592.         return -1
  9593.     
  9594.  
  9595. def is_promisc(ip, fake_bcast="ff:ff:00:00:00:00",**kargs):
  9596.     """Try to guess if target is in Promisc mode. The target is provided by its ip."""
  9597.  
  9598.     responses = srp1(Ether(dst=fake_bcast) / ARP(op="who-has", pdst=ip),type=ETH_P_ARP, iface_hint=ip, timeout=1, verbose=0,**kargs)
  9599.     print responses
  9600.  
  9601.     if responses is None:
  9602.         return False
  9603.     return True
  9604.  
  9605.  
  9606. def ikescan(ip):
  9607.     return sr(IP(dst=ip)/UDP()/ISAKMP(init_cookie=RandString(8),
  9608.                                       exch_type=2)/ISAKMP_payload_SA(prop=ISAKMP_payload_Proposal()))
  9609.  
  9610.  
  9611. def dhcp_request(iface=None,**kargs):
  9612.     if conf.checkIPaddr != 0:
  9613.         warning("conf.checkIPaddr is not 0, I may not be able to match the answer")
  9614.     if iface is None:
  9615.         iface = conf.iface
  9616.     fam,hw = get_if_raw_hwaddr(iface)
  9617.     return srp1(Ether(dst="ff:ff:ff:ff:ff:ff")/IP(src="0.0.0.0",dst="255.255.255.255")/UDP(sport=68,dport=67)
  9618.                  /BOOTP(chaddr=hw)/DHCP(options=[("message-type","discover"),"end"]),iface=iface,**kargs)
  9619.  
  9620.  
  9621. #####################
  9622. ## Reporting stuff ##
  9623. #####################
  9624.  
  9625. def report_ports(target, ports):
  9626.     """portscan a target and output a LaTeX table
  9627. report_ports(target, ports) -> string"""
  9628.     ans,unans = sr(IP(dst=target)/TCP(dport=ports),timeout=5)
  9629.     rep = "\\begin{tabular}{|r|l|l|}\n\\hline\n"
  9630.     for s,r in ans:
  9631.         if not r.haslayer(ICMP):
  9632.             if r.payload.flags == 0x12:
  9633.                 rep += r.sprintf("%TCP.sport% & open & SA \\\\\n")
  9634.     rep += "\\hline\n"
  9635.     for s,r in ans:
  9636.         if r.haslayer(ICMP):
  9637.             rep += r.sprintf("%TCPerror.dport% & closed & ICMP type %ICMP.type%/%ICMP.code% from %IP.src% \\\\\n")
  9638.         elif r.payload.flags != 0x12:
  9639.             rep += r.sprintf("%TCP.sport% & closed & TCP %TCP.flags% \\\\\n")
  9640.     rep += "\\hline\n"
  9641.     for i in unans:
  9642.         rep += i.sprintf("%TCP.dport% & ? & unanswered \\\\\n")
  9643.     rep += "\\hline\n\\end{tabular}\n"
  9644.     return rep
  9645.  
  9646.  
  9647. def __make_table(yfmtfunc, fmtfunc, endline, list, fxyz, sortx=None, sorty=None):
  9648.     vx = {}
  9649.     vy = {}
  9650.     vz = {}
  9651.     l = 0
  9652.     for e in list:
  9653.         xx,yy,zz = map(str, fxyz(e))
  9654.         l = max(len(yy),l)
  9655.         vx[xx] = max(vx.get(xx,0), len(xx), len(zz))
  9656.         vy[yy] = None
  9657.         vz[(xx,yy)] = zz
  9658.  
  9659.     vxk = vx.keys()
  9660.     vyk = vy.keys()
  9661.     if sortx:
  9662.         vxk.sort(sortx)
  9663.     else:
  9664.         try:
  9665.             vxk.sort(lambda x,y:int(x)-int(y))
  9666.         except:
  9667.             try:
  9668.                 vxk.sort(lambda x,y: cmp(struct.unpack("I", inet_aton(x))[0],struct.unpack("I", inet_aton(y))[0]))
  9669.             except:
  9670.                 vxk.sort()
  9671.     if sorty:
  9672.         vyk.sort(sorty)
  9673.     else:
  9674.         try:
  9675.             vyk.sort(lambda x,y:int(x)-int(y))
  9676.         except:
  9677.             try:
  9678.                 vyk.sort(lambda x,y: cmp(struct.unpack("I", inet_aton(x))[0],struct.unpack("I", inet_aton(y))[0]))
  9679.             except:
  9680.                 vyk.sort()
  9681.  
  9682.     fmt = yfmtfunc(l)
  9683.     print fmt % "",
  9684.     for x in vxk:
  9685.         vx[x] = fmtfunc(vx[x])
  9686.         print vx[x] % x,
  9687.     print endline
  9688.     for y in vyk:
  9689.         print fmt % y,
  9690.         for x in vxk:
  9691.             print vx[x] % vz.get((x,y), "-"),
  9692.         print endline
  9693.  
  9694. def make_table(*args, **kargs):
  9695.     __make_table(lambda l:"%%-%is" % l, lambda l:"%%-%is" % l, "", *args, **kargs)
  9696.     
  9697. def make_lined_table(*args, **kargs):
  9698.     __make_table(lambda l:"%%-%is |" % l, lambda l:"%%-%is |" % l, "", *args, **kargs)
  9699.  
  9700. def make_tex_table(*args, **kargs):
  9701.     __make_table(lambda l: "%s", lambda l: "& %s", "\\\\", *args, **kargs)
  9702.     
  9703.  
  9704. ######################
  9705. ## Online doc stuff ##
  9706. ######################
  9707.  
  9708.  
  9709. def lsc(cmd=None):
  9710.     """List user commands"""
  9711.     if cmd is None:
  9712.         for c in user_commands:
  9713.             doc = "No doc. available"
  9714.             if c.__doc__:
  9715.                 doc = c.__doc__.split("\n")[0]
  9716.             
  9717.             print "%-16s : %s" % (c.__name__, doc)
  9718.     else:
  9719.         print cmd.__doc__
  9720.  
  9721. def ls(obj=None):
  9722.     """List  available layers, or infos on a given layer"""
  9723.     if obj is None:
  9724.         import __builtin__
  9725.         objlst = filter(lambda (n,o): type(o) is types.TypeType and issubclass(o,Packet), __builtin__.__dict__.items())
  9726.         objlst.sort(lambda x,y:cmp(x[0],y[0]))
  9727.         for n,o in objlst:
  9728.             print "%-10s : %s" %(n,o.name)
  9729.     else:
  9730.         if type(obj) is types.TypeType and issubclass(obj, Packet):
  9731.             for f in obj.fields_desc:
  9732.                 print "%-10s : %-20s = (%s)" % (f.name, f.__class__.__name__,  repr(f.default))
  9733.         elif isinstance(obj, Packet):
  9734.             for f in obj.fields_desc:
  9735.                 print "%-10s : %-20s = %-15s (%s)" % (f.name, f.__class__.__name__, repr(getattr(obj,f.name)), repr(f.default))
  9736.             if not isinstance(obj.payload, NoPayload):
  9737.                 print "--"
  9738.                 ls(obj.payload)
  9739.                 
  9740.  
  9741.         else:
  9742.             print "Not a packet class. Type 'ls()' to list packet classes."
  9743.  
  9744.  
  9745.     
  9746.  
  9747.  
  9748. user_commands = [ sr, sr1, srp, srp1, srloop, srploop, sniff, p0f, arpcachepoison, send, sendp, traceroute, arping, ls, lsc, queso, nmap_fp, report_ports, dyndns_add, dyndns_del, is_promisc ]
  9749.  
  9750.  
  9751. ########################
  9752. ## Answering machines ##
  9753. ########################
  9754.  
  9755. class ReferenceAM(type):
  9756.     def __new__(cls, name, bases, dct):
  9757.         o = super(ReferenceAM, cls).__new__(cls, name, bases, dct)
  9758.         if o.function_name:
  9759.             globals()[o.function_name] = lambda o=o,*args,**kargs: o(*args,**kargs)()
  9760.         return o
  9761.  
  9762.  
  9763. class AnsweringMachine(object):
  9764.     __metaclass__ = ReferenceAM
  9765.     function_name = ""
  9766.     filter = None
  9767.     sniff_options = { "store":0 }
  9768.     sniff_options_list = [ "store", "iface", "count", "promisc", "filter", "type", "prn" ]
  9769.     send_options = { "verbose":0 }
  9770.     send_options_list = ["iface", "inter", "loop", "verbose"]
  9771.     send_function = staticmethod(send)
  9772.     
  9773.     
  9774.     def __init__(self, **kargs):
  9775.         self.mode = 0
  9776.         if self.filter:
  9777.             kargs.setdefault("filter",self.filter)
  9778.         kargs.setdefault("prn", self.reply)
  9779.         self.optam1 = {}
  9780.         self.optam2 = {}
  9781.         self.optam0 = {}
  9782.         doptsend,doptsniff = self.parse_all_options(1, kargs)
  9783.         self.defoptsend = self.send_options.copy()
  9784.         self.defoptsend.update(doptsend)
  9785.         self.defoptsniff = self.sniff_options.copy()
  9786.         self.defoptsniff.update(doptsniff)
  9787.         self.optsend,self.optsniff = [{},{}]
  9788.  
  9789.     def __getattr__(self, attr):
  9790.         for d in [self.optam2, self.optam1]:
  9791.             if attr in d:
  9792.                 return d[attr]
  9793.         raise AttributeError,attr
  9794.                 
  9795.     def __setattr__(self, attr, val):
  9796.         mode = self.__dict__.get("mode",0)
  9797.         if mode == 0:
  9798.             self.__dict__[attr] = val
  9799.         else:
  9800.             [self.optam1, self.optam2][mode-1][attr] = val
  9801.  
  9802.     def parse_options(self):
  9803.         pass
  9804.  
  9805.     def parse_all_options(self, mode, kargs):
  9806.         sniffopt = {}
  9807.         sendopt = {}
  9808.         for k in kargs.keys():            
  9809.             if k in self.sniff_options_list:
  9810.                 sniffopt[k] = kargs[k]
  9811.             if k in self.send_options_list:
  9812.                 sendopt[k] = kargs[k]
  9813.             if k in self.sniff_options_list+self.send_options_list:
  9814.                 del(kargs[k])
  9815.         if mode != 2 or kargs:
  9816.             if mode == 1:
  9817.                 self.optam0 = kargs
  9818.             elif mode == 2 and kargs:
  9819.                 k = self.optam0.copy()
  9820.                 k.update(kargs)
  9821.                 self.parse_options(**k)
  9822.                 kargs = k 
  9823.             omode = self.__dict__.get("mode",0)
  9824.             self.__dict__["mode"] = mode
  9825.             self.parse_options(**kargs)
  9826.             self.__dict__["mode"] = omode
  9827.         return sendopt,sniffopt
  9828.  
  9829.     def is_request(self, req):
  9830.         return 1
  9831.  
  9832.     def make_reply(self, req):
  9833.         return req
  9834.  
  9835.     def send_reply(self, reply):
  9836.         self.send_function(reply, **self.optsend)
  9837.  
  9838.     def print_reply(self, req, reply):
  9839.         print "%s ==> %s" % (req.summary(),reply.summary())
  9840.  
  9841.     def reply(self, pkt):
  9842.         if not self.is_request(pkt):
  9843.             return
  9844.         reply = self.make_reply(pkt)
  9845.         self.send_reply(reply)
  9846.         if conf.verb >= 0:
  9847.             self.print_reply(pkt, reply)
  9848.  
  9849.     def run(self, *args, **kargs):
  9850.         log_interactive.warning("run() method deprecated. The intance is now callable")
  9851.         self(*args,**kargs)
  9852.  
  9853.     def __call__(self, *args, **kargs):
  9854.         optsend,optsniff = self.parse_all_options(2,kargs)
  9855.         self.optsend=self.defoptsend.copy()
  9856.         self.optsend.update(optsend)
  9857.         self.optsniff=self.defoptsniff.copy()
  9858.         self.optsniff.update(optsniff)
  9859.  
  9860.         try:
  9861.             self.sniff()
  9862.         except KeyboardInterrupt:
  9863.             print "Interrupted by user"
  9864.         
  9865.     def sniff(self):
  9866.         sniff(**self.optsniff)
  9867.  
  9868.  
  9869. class BOOTP_am(AnsweringMachine):
  9870.     function_name = "bootpd"
  9871.     filter = "udp and port 68 and port 67"
  9872.     send_function = staticmethod(sendp)
  9873.     def parse_options(self, ipset=Net("192.168.1.128/25"),gw="192.168.1.1"):
  9874.         if type(ipset) is str:
  9875.             ipset = Net(ipset)
  9876.         if isinstance(ipset,Gen):
  9877.             ipset = [k for k in ipset]
  9878.             ipset.reverse()
  9879.         if len(ipset) == 1:
  9880.             ipset, = ipset
  9881.         self.ipset = ipset
  9882.         self.gw = gw
  9883.         self.leases = {}
  9884.  
  9885.     def is_request(self, req):
  9886.         if not req.haslayer(BOOTP):
  9887.             return 0
  9888.         reqb = req.getlayer(BOOTP)
  9889.         if reqb.op != 1:
  9890.             return 0
  9891.         return 1
  9892.  
  9893.     def print_reply(self, req, reply):
  9894.         print "Reply %s to %s" % (reply.getlayer(IP).dst,reply.dst)
  9895.  
  9896.     def make_reply(self, req):        
  9897.         mac = req.src
  9898.         if type(self.ipset) is list:
  9899.             if not self.leases.has_key(mac):
  9900.                 self.leases[mac] = self.ipset.pop()
  9901.             ip = self.leases[mac]
  9902.         else:
  9903.             ip = self.ipset
  9904.             
  9905.         repb = req.getlayer(BOOTP).copy()
  9906.         repb.options = ""
  9907.         repb.op="BOOTREPLY"
  9908.         repb.yiaddr = ip
  9909.         repb.siaddr = self.gw
  9910.         repb.ciaddr = self.gw
  9911.         repb.giaddr = self.gw
  9912.         rep=Ether(dst=mac)/IP(dst=ip)/UDP(sport=req.dport,dport=req.sport)/repb
  9913.         return rep
  9914.  
  9915.  
  9916. class DHCP_am(BOOTP_am):
  9917.     function_name="dhcpd"
  9918.     def is_request(self, req):
  9919.         if not BOOTP_am.is_request(self, req):
  9920.             return 0
  9921.         if req.getlayer(BOOTP).options[:4] != "'c\x82Sc":
  9922.             return 0
  9923.         return 1
  9924.     def make_reply(self, req):
  9925.         dhcprespmap={"\x01":"\x02","\x03":"\x05"}
  9926.         resp = BOOTP_am.make_reply(self, req)
  9927.         opt = req.getlayer(BOOTP).options
  9928.         o = opt[:6]
  9929.         if len(opt) > 6:
  9930.             o += dhcprespmap.get(opt[6],opt[6])
  9931.         if len(opt) > 7:
  9932.             o += opt[7:]
  9933.         resp.getlayer(BOOTP).options = o
  9934.  
  9935.  
  9936.  
  9937. class DNS_am(AnsweringMachine):
  9938.     function_name="dns_spoof"
  9939.     filter = "udp port 53"
  9940.  
  9941.     def parse_options(self, joker="192.168.1.1", match=None):
  9942.         if match is None:
  9943.             self.match = {}
  9944.         else:
  9945.             self.match = match
  9946.         self.joker=joker
  9947.  
  9948.     def is_request(self, req):
  9949.         return req.haslayer(DNS) and req.getlayer(DNS).qr == 0
  9950.     
  9951.     def make_reply(self, req):
  9952.         ip = req.getlayer(IP)
  9953.         dns = req.getlayer(DNS)
  9954.         resp = IP(dst=ip.src, src=ip.dst)/UDP(dport=ip.sport,sport=ip.dport)
  9955.         rdata = self.match.get(dns.qd.qname, self.joker)
  9956.         resp /= DNS(id=dns.id, qr=1, qd=dns.qd,
  9957.                     an=DNSRR(rrname=dns.qd.qname, ttl=10, rdata=rdata))
  9958.         return resp
  9959.  
  9960.  
  9961. class WiFi_am(AnsweringMachine):
  9962.     """Before using this, initialize "iffrom" and "ifto" interfaces:
  9963. iwconfig iffrom mode monitor
  9964. iwpriv orig_ifto hostapd 1
  9965. ifconfig ifto up
  9966. note: if ifto=wlan0ap then orig_ifto=wlan0
  9967. note: ifto and iffrom must be set on the same channel
  9968. ex:
  9969. ifconfig eth1 up
  9970. iwconfig eth1 mode monitor
  9971. iwconfig eth1 channel 11
  9972. iwpriv wlan0 hostapd 1
  9973. ifconfig wlan0ap up
  9974. iwconfig wlan0 channel 11
  9975. iwconfig wlan0 essid dontexist
  9976. iwconfig wlan0 mode managed
  9977. """
  9978.     function_name = "airpwn"
  9979.     filter = None
  9980.     
  9981.     def parse_options(iffrom, ifto, replace, pattern="", ignorepattern=""):
  9982.         self.iffrom = iffrom
  9983.         self.ifto = ifto
  9984.         ptrn = re.compile(pattern)
  9985.         iptrn = re.compile(ignorepattern)
  9986.         
  9987.     def is_request(self, pkt):
  9988.         if not isinstance(pkt,Dot11):
  9989.             return 0
  9990.         if not pkt.FCfield & 1:
  9991.             return 0
  9992.         if not pkt.haslayer(TCP):
  9993.             return 0
  9994.         ip = pkt.getlayer(IP)
  9995.         tcp = pkt.getlayer(TCP)
  9996.         pay = str(tcp.payload)
  9997.         if not self.ptrn.match(pay):
  9998.             return 0
  9999.         if self.iptrn.match(pay):
  10000.             return 0
  10001.  
  10002.     def make_reply(self, p):
  10003.         ip = p.getlayer(IP)
  10004.         tcp = p.getlayer(TCP)
  10005.         pay = str(tcp.payload)
  10006.         del(p.payload.payload.payload)
  10007.         p.FCfield="from-DS"
  10008.         p.addr1,p.addr2 = p.addr2,p.addr1
  10009.         p /= IP(src=ip.dst,dst=ip.src)
  10010.         p /= TCP(sport=tcp.dport, dport=tcp.sport,
  10011.                  seq=tcp.ack, ack=tcp.seq+len(pay),
  10012.                  flags="PA")
  10013.         q = p.copy()
  10014.         p /= self.replace
  10015.         q.ID += 1
  10016.         q.getlayer(TCP).flags="RA"
  10017.         q.getlayer(TCP).seq+=len(replace)
  10018.         return [p,q]
  10019.     
  10020.     def print_reply(self):
  10021.         print p.sprintf("Sent %IP.src%:%IP.sport% > %IP.dst%:%TCP.dport%")
  10022.  
  10023.     def send_reply(self, reply):
  10024.         sendp(reply, iface=self.ifto, **self.optsend)
  10025.  
  10026.     def sniff(self):
  10027.         sniff(iface=self.iffrom, **self.optsniff)
  10028.  
  10029.  
  10030.  
  10031. class ARP_am(AnsweringMachine):
  10032.     function_name="farpd"
  10033.     filter = "arp"
  10034.     send_function = staticmethod(sendp)
  10035.  
  10036.     def parse_options(self, IP_addr=None, iface=None, ARP_addr=None):
  10037.         self.IP_addr=IP_addr
  10038.         self.iface=iface
  10039.         self.ARP_addr=ARP_addr
  10040.  
  10041.     def is_request(self, req):
  10042.         return (req.haslayer(ARP) and
  10043.                 req.getlayer(ARP).op == 1 and
  10044.                 (self.IP_addr == None or self.IP_addr == req.getlayer(ARP).pdst))
  10045.     
  10046.     def make_reply(self, req):
  10047.         ether = req.getlayer(Ether)
  10048.         arp = req.getlayer(ARP)
  10049.         iff,a,gw = conf.route.route(arp.psrc)
  10050.         if self.iface != None:
  10051.             iff = iface
  10052.         ARP_addr = self.ARP_addr
  10053.         IP_addr = arp.pdst
  10054.         resp = Ether(dst=ether.src,
  10055.                      src=ARP_addr)/ARP(op="is-at",
  10056.                                        hwsrc=ARP_addr,
  10057.                                        psrc=IP_addr,
  10058.                                        hwdst=arp.hwsrc,
  10059.                                        pdst=arp.pdst)
  10060.         return resp
  10061.  
  10062.     def sniff(self):
  10063.         sniff(iface=self.iface, **self.optsniff)
  10064.  
  10065.  
  10066. #############
  10067. ## Fuzzing ##
  10068. #############
  10069.  
  10070.  
  10071. def fuzz(p):
  10072.     p = q = p.copy()
  10073.     while not isinstance(q, NoPayload):
  10074.         for f in q.fields_desc:
  10075.             if f.default is not None:
  10076.                 rnd = f.randval()
  10077.                 if rnd is not None:
  10078.                     q.default_fields[f] = rnd
  10079.         q = q.payload
  10080.     return p
  10081.  
  10082.  
  10083.  
  10084.  
  10085. ###################
  10086. ## Testing stuff ##
  10087. ###################
  10088.  
  10089.  
  10090.  
  10091. def merge(x,y):
  10092.     if len(x) > len(y):
  10093.         y += "\x00"*(len(x)-len(y))
  10094.     elif len(x) < len(y):
  10095.         x += "\x00"*(len(y)-len(x))
  10096.     m = ""
  10097.     for i in range(len(x)/ss):
  10098.         m += x[ss*i:ss*(i+1)]+y[ss*i:ss*(i+1)]
  10099.     return  m
  10100. #    return  "".join(map(str.__add__, x, y))
  10101.  
  10102.  
  10103. def voip_play(s1,list=None,**kargs):
  10104.     FIFO="/tmp/conv1.%i.%%i" % os.getpid()
  10105.     FIFO1=FIFO % 1
  10106.     FIFO2=FIFO % 2
  10107.     
  10108.     os.mkfifo(FIFO1)
  10109.     os.mkfifo(FIFO2)
  10110.     try:
  10111.         os.system("soxmix -t .ul %s -t .ul %s -t ossdsp /dev/dsp &" % (FIFO1,FIFO2))
  10112.         
  10113.         c1=open(FIFO1,"w", 4096)
  10114.         c2=open(FIFO2,"w", 4096)
  10115.         fcntl.fcntl(c1.fileno(),fcntl.F_SETFL, os.O_NONBLOCK)
  10116.         fcntl.fcntl(c2.fileno(),fcntl.F_SETFL, os.O_NONBLOCK)
  10117.     
  10118.     #    dsp,rd = os.popen2("sox -t .ul -c 2 - -t ossdsp /dev/dsp")
  10119.         def play(pkt,last=[]):
  10120.             if not pkt:
  10121.                 return 
  10122.             if not pkt.haslayer(UDP):
  10123.                 return 
  10124.             ip=pkt.getlayer(IP)
  10125.             if s1 in [ip.src, ip.dst]:
  10126.                 if not last:
  10127.                     last.append(pkt)
  10128.                     return
  10129.                 load=last.pop()
  10130.     #            x1 = load.load[12:]
  10131.                 c1.write(load.load[12:])
  10132.                 if load.getlayer(IP).src == ip.src:
  10133.     #                x2 = ""
  10134.                     c2.write("\x00"*len(load.load[12:]))
  10135.                     last.append(pkt)
  10136.                 else:
  10137.     #                x2 = pkt.load[:12]
  10138.                     c2.write(pkt.load[12:])
  10139.     #            dsp.write(merge(x1,x2))
  10140.     
  10141.         if list is None:
  10142.             sniff(store=0, prn=play, **kargs)
  10143.         else:
  10144.             for p in list:
  10145.                 play(p)
  10146.     finally:
  10147.         os.unlink(FIFO1)
  10148.         os.unlink(FIFO2)
  10149.  
  10150.  
  10151.  
  10152. def voip_play1(s1,list=None,**kargs):
  10153.  
  10154.     
  10155.     dsp,rd = os.popen2("sox -t .ul - -t ossdsp /dev/dsp")
  10156.     def play(pkt):
  10157.         if not pkt:
  10158.             return 
  10159.         if not pkt.haslayer(UDP):
  10160.             return 
  10161.         ip=pkt.getlayer(IP)
  10162.         if s1 in [ip.src, ip.dst]:
  10163.             dsp.write(pkt.getlayer(Raw).load[12:])
  10164.     try:
  10165.         if list is None:
  10166.             sniff(store=0, prn=play, **kargs)
  10167.         else:
  10168.             for p in list:
  10169.                 play(p)
  10170.     finally:
  10171.         dsp.close()
  10172.         rd.close()
  10173.  
  10174. def voip_play2(s1,**kargs):
  10175.     dsp,rd = os.popen2("sox -t .ul -c 2 - -t ossdsp /dev/dsp")
  10176.     def play(pkt,last=[]):
  10177.         if not pkt:
  10178.             return 
  10179.         if not pkt.haslayer(UDP):
  10180.             return 
  10181.         ip=pkt.getlayer(IP)
  10182.         if s1 in [ip.src, ip.dst]:
  10183.             if not last:
  10184.                 last.append(pkt)
  10185.                 return
  10186.             load=last.pop()
  10187.             x1 = load.load[12:]
  10188. #            c1.write(load.load[12:])
  10189.             if load.getlayer(IP).src == ip.src:
  10190.                 x2 = ""
  10191. #                c2.write("\x00"*len(load.load[12:]))
  10192.                 last.append(pkt)
  10193.             else:
  10194.                 x2 = pkt.load[:12]
  10195. #                c2.write(pkt.load[12:])
  10196.             dsp.write(merge(x1,x2))
  10197.             
  10198.     sniff(store=0, prn=play, **kargs)
  10199.  
  10200. def voip_play3(lst=None,**kargs):
  10201.     dsp,rd = os.popen2("sox -t .ul - -t ossdsp /dev/dsp")
  10202.     try:
  10203.         def play(pkt, dsp=dsp):
  10204.             if pkt and pkt.haslayer(UDP) and pkt.haslayer(Raw):
  10205.                 dsp.write(pkt.getlayer(Raw).load[12:])
  10206.         if lst is None:
  10207.             sniff(store=0, prn=play, **kargs)
  10208.         else:
  10209.             for p in lst:
  10210.                 play(p)
  10211.     finally:
  10212.         try:
  10213.             dsp.close()
  10214.             rd.close()
  10215.         except:
  10216.             pass
  10217.  
  10218.  
  10219. def IPID_count(lst, funcID=lambda x:x[1].id, funcpres=lambda x:x[1].summary()):
  10220.     idlst = map(funcID, lst)
  10221.     idlst.sort()
  10222.     classes = [idlst[0]]+map(lambda x:x[1],filter(lambda (x,y): abs(x-y)>50, map(lambda x,y: (x,y),idlst[:-1], idlst[1:])))
  10223.     lst = map(lambda x:(funcID(x), funcpres(x)), lst)
  10224.     lst.sort()
  10225.     print "Probably %i classes:" % len(classes), classes
  10226.     for id,pr in lst:
  10227.         print "%5i" % id, pr
  10228.     
  10229.     
  10230.     
  10231.             
  10232.  
  10233. last=None
  10234.  
  10235.  
  10236. def tethereal(*args,**kargs):
  10237.     sniff(prn=lambda x: x.display(),*args,**kargs)
  10238.  
  10239.  
  10240.  
  10241. def fragleak(target,sport=123, dport=123, timeout=0.2, onlyasc=0):
  10242.     load = "XXXXYYYYYYYYYY"
  10243. #    getmacbyip(target)
  10244. #    pkt = IP(dst=target, id=RandShort(), options="\x22"*40)/UDP()/load
  10245.     pkt = IP(dst=target, id=RandShort(), options="\x00"*40, flags=1)/UDP(sport=sport, dport=sport)/load
  10246.     s=conf.L3socket()
  10247.     intr=0
  10248.     found={}
  10249.     try:
  10250.         while 1:
  10251.             try:
  10252.                 if not intr:
  10253.                     s.send(pkt)
  10254.                 sin,sout,serr = select([s],[],[],timeout)
  10255.                 if not sin:
  10256.                     continue
  10257.                 ans=s.recv(1600)
  10258.                 if not isinstance(ans, IP): #TODO: IPv6
  10259.                     continue
  10260.                 if not isinstance(ans.payload, ICMP):
  10261.                     continue
  10262.                 if not isinstance(ans.payload.payload, IPerror):
  10263.                     continue
  10264.                 if ans.payload.payload.dst != target:
  10265.                     continue
  10266.                 if ans.src  != target:
  10267.                     print "leak from", ans.src,
  10268.  
  10269.  
  10270. #                print repr(ans)
  10271.                 if not ans.haslayer(Padding):
  10272.                     continue
  10273.  
  10274.                 
  10275. #                print repr(ans.payload.payload.payload.payload)
  10276.                 
  10277. #                if not isinstance(ans.payload.payload.payload.payload, Raw):
  10278. #                    continue
  10279. #                leak = ans.payload.payload.payload.payload.load[len(load):]
  10280.                 leak = ans.getlayer(Padding).load
  10281.                 if leak not in found:
  10282.                     found[leak]=None
  10283.                     linehexdump(leak, onlyasc=onlyasc)
  10284.             except KeyboardInterrupt:
  10285.                 if intr:
  10286.                     raise KeyboardInterrupt
  10287.                 intr=1
  10288.     except KeyboardInterrupt:
  10289.         pass
  10290.  
  10291. def fragleak2(target, timeout=0.4, onlyasc=0):
  10292.     found={}
  10293.     try:
  10294.         while 1:
  10295.             p = sr1(IP(dst=target, options="\x00"*40, proto=200)/"XXXXYYYYYYYYYYYY",timeout=timeout,verbose=0)
  10296.             if not p:
  10297.                 continue
  10298.             if Padding in p:
  10299.                 leak  = p[Padding].load
  10300.                 if leak not in found:
  10301.                     found[leak]=None
  10302.                     linehexdump(leak,onlyasc=onlyasc)
  10303.     except:
  10304.         pass
  10305.     
  10306.  
  10307.  
  10308. plst=[]
  10309. def get_toDS():
  10310.     global plst
  10311.     while 1:
  10312.         p,=sniff(iface="eth1",count=1)
  10313.         if not isinstance(p,Dot11):
  10314.             continue
  10315.         if p.FCfield & 1:
  10316.             plst.append(p)
  10317.             print "."
  10318.  
  10319.  
  10320. #    if not ifto.endswith("ap"):
  10321. #        print "iwpriv %s hostapd 1" % ifto
  10322. #        os.system("iwpriv %s hostapd 1" % ifto)
  10323. #        ifto += "ap"
  10324. #        
  10325. #    os.system("iwconfig %s mode monitor" % iffrom)
  10326. #    
  10327.  
  10328. def airpwn(iffrom, ifto, replace, pattern="", ignorepattern=""):
  10329.     """Before using this, initialize "iffrom" and "ifto" interfaces:
  10330. iwconfig iffrom mode monitor
  10331. iwpriv orig_ifto hostapd 1
  10332. ifconfig ifto up
  10333. note: if ifto=wlan0ap then orig_ifto=wlan0
  10334. note: ifto and iffrom must be set on the same channel
  10335. ex:
  10336. ifconfig eth1 up
  10337. iwconfig eth1 mode monitor
  10338. iwconfig eth1 channel 11
  10339. iwpriv wlan0 hostapd 1
  10340. ifconfig wlan0ap up
  10341. iwconfig wlan0 channel 11
  10342. iwconfig wlan0 essid dontexist
  10343. iwconfig wlan0 mode managed
  10344. """
  10345.     
  10346.     ptrn = re.compile(pattern)
  10347.     iptrn = re.compile(ignorepattern)
  10348.     def do_airpwn(p, ifto=ifto, replace=replace, ptrn=ptrn, iptrn=iptrn):
  10349.         if not isinstance(p,Dot11):
  10350.             return
  10351.         if not p.FCfield & 1:
  10352.             return
  10353.         if not p.haslayer(TCP):
  10354.             return
  10355.         ip = p.getlayer(IP)
  10356.         tcp = p.getlayer(TCP)
  10357.         pay = str(tcp.payload)
  10358. #        print "got tcp"
  10359.         if not ptrn.match(pay):
  10360.             return
  10361. #        print "match 1"
  10362.         if iptrn.match(pay):
  10363.             return
  10364. #        print "match 2"
  10365.         del(p.payload.payload.payload)
  10366.         p.FCfield="from-DS"
  10367.         p.addr1,p.addr2 = p.addr2,p.addr1
  10368.         q = p.copy()
  10369.         p /= IP(src=ip.dst,dst=ip.src)
  10370.         p /= TCP(sport=tcp.dport, dport=tcp.sport,
  10371.                  seq=tcp.ack, ack=tcp.seq+len(pay),
  10372.                  flags="PA")
  10373.         q = p.copy()
  10374.         p /= replace
  10375.         q.ID += 1
  10376.         q.getlayer(TCP).flags="RA"
  10377.         q.getlayer(TCP).seq+=len(replace)
  10378.         
  10379.         sendp([p,q], iface=ifto, verbose=0)
  10380. #        print "send",repr(p)        
  10381. #        print "send",repr(q)
  10382.         print p.sprintf("Sent %IP.src%:%IP.sport% > %IP.dst%:%TCP.dport%")
  10383.  
  10384.     sniff(iface=iffrom,prn=do_airpwn)
  10385.  
  10386.             
  10387.         
  10388.     
  10389. ##################
  10390. ## Color themes ##
  10391. ##################
  10392.  
  10393. class Color:
  10394.     normal = "\033[0m"
  10395.     black = "\033[30m"
  10396.     red = "\033[31m"
  10397.     green = "\033[32m"
  10398.     yellow = "\033[33m"
  10399.     blue = "\033[34m"
  10400.     purple = "\033[35m"
  10401.     cyan = "\033[36m"
  10402.     grey = "\033[37m"
  10403.  
  10404.     bold = "\033[1m"
  10405.     uline = "\033[4m"
  10406.     blink = "\033[5m"
  10407.     invert = "\033[7m"
  10408.         
  10409.  
  10410. class ColorTheme:
  10411.     def __repr__(self):
  10412.         return "<%s>" % self.__class__.__name__
  10413.     def __getattr__(self, attr):
  10414.         return lambda x:x
  10415.         
  10416.  
  10417. class NoTheme(ColorTheme):
  10418.     pass
  10419.  
  10420.  
  10421. class AnsiColorTheme(ColorTheme):
  10422.     def __getattr__(self, attr):
  10423.         s = "style_%s" % attr 
  10424.         if s in self.__class__.__dict__:
  10425.             before = getattr(self, s)
  10426.             after = self.style_normal
  10427.         else:
  10428.             before = after = ""
  10429.  
  10430.         def do_style(val, fmt=None, before=before, after=after):
  10431.             if fmt is None:
  10432.                 if type(val) is not str:
  10433.                     val = str(val)
  10434.             else:
  10435.                 val = fmt % val
  10436.             return before+val+after
  10437.         return do_style
  10438.         
  10439.         
  10440.     style_normal = ""
  10441.     style_prompt = ""
  10442.     style_punct = ""
  10443.     style_id = ""
  10444.     style_not_printable = ""
  10445.     style_layer_name = ""
  10446.     style_field_name = ""
  10447.     style_field_value = ""
  10448.     style_emph_field_name = ""
  10449.     style_emph_field_value = ""
  10450.     style_packetlist_name = ""
  10451.     style_packetlist_proto = ""
  10452.     style_packetlist_value = ""
  10453.     style_fail = ""
  10454.     style_success = ""
  10455.     style_odd = ""
  10456.     style_even = ""
  10457.     style_opening = ""
  10458.     style_active = ""
  10459.     style_closed = ""
  10460.  
  10461. class BlackAndWhite(AnsiColorTheme):
  10462.     pass
  10463.  
  10464. class DefaultTheme(AnsiColorTheme):
  10465.     style_normal = Color.normal
  10466.     style_prompt = Color.blue+Color.bold
  10467.     style_punct = Color.normal
  10468.     style_id = Color.blue+Color.bold
  10469.     style_not_printable = Color.grey
  10470.     style_layer_name = Color.red+Color.bold
  10471.     style_field_name = Color.blue
  10472.     style_field_value = Color.purple
  10473.     style_emph_field_name = Color.blue+Color.uline+Color.bold
  10474.     style_emph_field_value = Color.purple+Color.uline+Color.bold
  10475.     style_packetlist_name = Color.red+Color.bold
  10476.     style_packetlist_proto = Color.blue
  10477.     style_packetlist_value = Color.purple
  10478.     style_fail = Color.red+Color.bold
  10479.     style_success = Color.blue+Color.bold
  10480.     style_even = Color.black+Color.bold
  10481.     style_odd = Color.black
  10482.     style_opening = Color.yellow
  10483.     style_active = Color.black
  10484.     style_closed = Color.grey
  10485.     
  10486. class BrightTheme(AnsiColorTheme):
  10487.     style_normal = Color.normal
  10488.     style_punct = Color.normal
  10489.     style_id = Color.yellow+Color.bold
  10490.     style_layer_name = Color.red+Color.bold
  10491.     style_field_name = Color.yellow+Color.bold
  10492.     style_field_value = Color.purple+Color.bold
  10493.     style_emph_field_name = Color.yellow+Color.bold
  10494.     style_emph_field_value = Color.green+Color.bold
  10495.     style_packetlist_name = Color.red+Color.bold
  10496.     style_packetlist_proto = Color.yellow+Color.bold
  10497.     style_packetlist_value = Color.purple+Color.bold
  10498.     style_fail = Color.red+Color.bold
  10499.     style_success = Color.blue+Color.bold
  10500.     style_even = Color.black+Color.bold
  10501.     style_odd = Color.black
  10502.  
  10503.  
  10504. class RastaTheme(AnsiColorTheme):
  10505.     style_normal = Color.green+Color.bold
  10506.     style_prompt = Color.yellow+Color.bold
  10507.     style_punct = Color.red
  10508.     style_id = Color.green+Color.bold
  10509.     style_not_printable = Color.green
  10510.     style_layer_name = Color.red+Color.bold
  10511.     style_field_name = Color.yellow+Color.bold
  10512.     style_field_value = Color.green+Color.bold
  10513.     style_emph_field_name = Color.green
  10514.     style_emph_field_value = Color.green
  10515.     style_packetlist_name = Color.red+Color.bold
  10516.     style_packetlist_proto = Color.yellow+Color.bold
  10517.     style_packetlist_value = Color.green+Color.bold
  10518.     style_fail = Color.red
  10519.     style_success = Color.red+Color.bold
  10520.     style_even = Color.yellow
  10521.     style_odd = Color.green
  10522.  
  10523.  
  10524. class FormatTheme(ColorTheme):
  10525.     def __getattr__(self, attr):
  10526.         col = self.__class__.__dict__.get("style_%s" % attr, "%s")
  10527.         def do_style(val, fmt=None, col=col):
  10528.             if fmt is None:
  10529.                 if type(val) is not str:
  10530.                     val = str(val)
  10531.             else:
  10532.                 val = fmt % val
  10533.             return col % val
  10534.         return do_style
  10535.         
  10536.  
  10537. class LatexTheme(FormatTheme):
  10538.     style_prompt = r"\textcolor{blue}{%s}"
  10539.     style_not_printable = r"\textcolor{gray}{%s}"
  10540.     style_layer_name = r"\textcolor{red}{\bf %s}"
  10541.     style_field_name = r"\textcolor{blue}{%s}"
  10542.     style_field_value = r"\textcolor{purple}{%s}"
  10543.     style_emph_field_name = r"\textcolor{blue}{\underline{%s}}" #ul
  10544.     style_emph_field_value = r"\textcolor{purple}{\underline{%s}}" #ul
  10545.     style_packetlist_name = r"\textcolor{red}{\bf %s}"
  10546.     style_packetlist_proto = r"\textcolor{blue}{%s}"
  10547.     style_packetlist_value = r"\textcolor{purple}{%s}"
  10548.     style_fail = r"\textcolor{red}{\bf %s}"
  10549.     style_success = r"\textcolor{blue}{\bf %s}"
  10550. #    style_even = r"}{\bf "
  10551. #    style_odd = ""
  10552.  
  10553. class LatexTheme2(FormatTheme):
  10554.     style_prompt = r"@`@textcolor@[@blue@]@@[@%s@]@"
  10555.     style_not_printable = r"@`@textcolor@[@gray@]@@[@%s@]@"
  10556.     style_layer_name = r"@`@textcolor@[@red@]@@[@@`@bf %s@]@"
  10557.     style_field_name = r"@`@textcolor@[@blue@]@@[@%s@]@"
  10558.     style_field_value = r"@`@textcolor@[@purple@]@@[@%s@]@"
  10559.     style_emph_field_name = r"@`@textcolor@[@blue@]@@[@@`@underline@[@%s@]@@]@" 
  10560.     style_emph_field_value = r"@`@textcolor@[@purple@]@@[@@`@underline@[@%s@]@@]@" 
  10561.     style_packetlist_name = r"@`@textcolor@[@red@]@@[@@`@bf %s@]@"
  10562.     style_packetlist_proto = r"@`@textcolor@[@blue@]@@[@%s@]@"
  10563.     style_packetlist_value = r"@`@textcolor@[@purple@]@@[@%s@]@"
  10564.     style_fail = r"@`@textcolor@[@red@]@@[@@`@bf %s@]@"
  10565.     style_success = r"@`@textcolor@[@blue@]@@[@@`@bf %s@]@"
  10566. #    style_even = r"}{\bf "
  10567. #    style_odd = ""
  10568.  
  10569. class HTMLTheme(FormatTheme):
  10570.     style_prompt = "<span class=prompt>%s</span>"
  10571.     style_not_printable = "<span class=not_printable>%s</span>"
  10572.     style_layer_name = "<span class=layer_name>%s</span>"
  10573.     style_field_name = "<span class=field_name>%s</span>"
  10574.     style_field_value = "<span class=field_value>%s</span>"
  10575.     style_emph_field_name = "<span class=emph_field_name>%s</span>"
  10576.     style_emph_field_value = "<span class=emph_field_value>%s</span>"
  10577.     style_packetlist_name = "<span class=packetlist_name>%s</span>"
  10578.     style_packetlist_proto = "<span class=packetlist_proto>%s</span>"
  10579.     style_packetlist_value = "<span class=packetlist_value>%s</span>"
  10580.     style_fail = "<span class=fail>%s</span>"
  10581.     style_success = "<span class=success>%s</span>"
  10582.     style_even = "<span class=even>%s</span>"
  10583.     style_odd = "<span class=odd>%s</span>"
  10584.  
  10585. class HTMLTheme2(HTMLTheme):
  10586.     style_prompt = "#[#span class=prompt#]#%s#[#/span#]#"
  10587.     style_not_printable = "#[#span class=not_printable#]#%s#[#/span#]#"
  10588.     style_layer_name = "#[#span class=layer_name#]#%s#[#/span#]#"
  10589.     style_field_name = "#[#span class=field_name#]#%s#[#/span#]#"
  10590.     style_field_value = "#[#span class=field_value#]#%s#[#/span#]#"
  10591.     style_emph_field_name = "#[#span class=emph_field_name#]#%s#[#/span#]#"
  10592.     style_emph_field_value = "#[#span class=emph_field_value#]#%s#[#/span#]#"
  10593.     style_packetlist_name = "#[#span class=packetlist_name#]#%s#[#/span#]#"
  10594.     style_packetlist_proto = "#[#span class=packetlist_proto#]#%s#[#/span#]#"
  10595.     style_packetlist_value = "#[#span class=packetlist_value#]#%s#[#/span#]#"
  10596.     style_fail = "#[#span class=fail#]#%s#[#/span#]#"
  10597.     style_success = "#[#span class=success#]#%s#[#/span#]#"
  10598.     style_even = "#[#span class=even#]#%s#[#/span#]#"
  10599.     style_odd = "#[#span class=odd#]#%s#[#/span#]#"
  10600.  
  10601.  
  10602. class ColorPrompt:
  10603.     __prompt = ">>> "
  10604.     def __str__(self):
  10605.         try:
  10606.             ct = conf.color_theme
  10607.             if isinstance(ct, AnsiColorTheme):
  10608.                 ## ^A and ^B delimit invisible caracters for readline to count right
  10609.                 return "\001%s\002" % ct.prompt("\002"+conf.prompt+"\001")
  10610.             else:
  10611.                 return ct.prompt(conf.prompt)
  10612.         except:
  10613.             return self.__prompt
  10614.  
  10615. ############
  10616. ## Config ##
  10617. ############
  10618.  
  10619. class ConfClass:
  10620.     def configure(self, cnf):
  10621.         self.__dict__ = cnf.__dict__.copy()
  10622.     def __repr__(self):
  10623.         return str(self)
  10624.     def __str__(self):
  10625.         s="Version    = %s\n" % VERSION
  10626.         keys = self.__class__.__dict__.copy()
  10627.         keys.update(self.__dict__)
  10628.         keys = keys.keys()
  10629.         keys.sort()
  10630.         for i in keys:
  10631.             if i[0] != "_":
  10632.                 s += "%-10s = %s\n" % (i, repr(getattr(self, i)))
  10633.         return s[:-1]
  10634.     def reset(self):
  10635.         self.__dict__ = {}
  10636.  
  10637.     
  10638. class ProgPath(ConfClass):
  10639.     pdfreader = "acroread"
  10640.     psreader = "gv"
  10641.     dot = "dot"
  10642.     display = "display"
  10643.     tcpdump = "tcpdump"
  10644.     
  10645.  
  10646.  
  10647. class Conf(ConfClass):
  10648.     """This object contains the configuration of scapy.
  10649. session  : filename where the session will be saved
  10650. stealth  : if 1, prevents any unwanted packet to go out (ARP, DNS, ...)
  10651. checkIPID: if 0, doesn't check that IPID matches between IP sent and ICMP IP citation received
  10652.            if 1, checks that they either are equal or byte swapped equals (bug in some IP stacks)
  10653.            if 2, strictly checks that they are equals
  10654. checkIPsrc: if 1, checks IP src in IP and ICMP IP citation match (bug in some NAT stacks)
  10655. check_TCPerror_seqack: if 1, also check that TCP seq and ack match the ones in ICMP citation
  10656. iff      : selects the default output interface for srp() and sendp(). default:"eth0")
  10657. verb     : level of verbosity, from 0 (almost mute) to 3 (verbose)
  10658. promisc  : default mode for listening socket (to get answers if you spoof on a lan)
  10659. sniff_promisc : default mode for sniff()
  10660. filter   : bpf filter added to every sniffing socket to exclude traffic from analysis
  10661. histfile : history file
  10662. padding  : includes padding in desassembled packets
  10663. except_filter : BPF filter for packets to ignore
  10664. debug_match : when 1, store received packet that are not matched into debug.recv
  10665. route    : holds the Scapy routing table and provides methods to manipulate it
  10666. warning_threshold : how much time between warnings from the same place
  10667. """
  10668.     session = ""  
  10669.     stealth = "not implemented"
  10670.     iface = get_working_if()
  10671.     checkIPID = 1
  10672.     checkIPsrc = 1
  10673.     checkIPaddr = 1
  10674.     check_TCPerror_seqack = 0
  10675.     verb = 2
  10676.     prompt = ">>> "
  10677.     promisc = 1
  10678.     sniff_promisc = 1
  10679.     L3socket = L3PacketSocket
  10680.     L2socket = L2Socket
  10681.     L2listen = L2ListenSocket
  10682.     BTsocket = BluetoothL2CAPSocket
  10683.     histfile = os.path.join(os.environ["HOME"], ".scapy_history")
  10684.     padding = 1
  10685.     p0f_base ="/etc/p0f.fp"
  10686.     queso_base ="/etc/queso.conf"
  10687.     nmap_base ="/usr/share/nmap/nmap-os-fingerprints"
  10688.     IPCountry_base = "GeoIPCountry4Scapy.gz"
  10689.     countryLoc_base = "countryLoc.csv"
  10690.     gnuplot_world = "world.dat"
  10691.     except_filter = ""
  10692.     debug_match = 0
  10693.     route = Route()
  10694.     wepkey = ""
  10695.     debug_dissector = 0
  10696.     color_theme = DefaultTheme()
  10697.     warning_threshold = 5
  10698.     prog = ProgPath()
  10699.         
  10700.  
  10701. conf=Conf()
  10702.  
  10703. if PCAP:
  10704.     conf.L2listen=L2pcapListenSocket
  10705.     if DNET:
  10706.         conf.L3socket=L3dnetSocket
  10707.         conf.L2socket=L2dnetSocket
  10708.  
  10709.  
  10710. p0f_kdb = p0fKnowledgeBase(conf.p0f_base)
  10711. queso_kdb = QuesoKnowledgeBase(conf.queso_base)
  10712. nmap_kdb = NmapKnowledgeBase(conf.nmap_base)
  10713. IP_country_kdb = IPCountryKnowledgeBase(conf.IPCountry_base)
  10714. country_loc_kdb = CountryLocKnowledgeBase(conf.countryLoc_base)
  10715.  
  10716.  
  10717. #########################
  10718. ##### Autorun stuff #####
  10719. #########################
  10720.  
  10721.  
  10722. class ScapyAutorunInterpreter(code.InteractiveInterpreter):
  10723.     def __init__(self, *args, **kargs):
  10724.         code.InteractiveInterpreter.__init__(self, *args, **kargs)
  10725.         self.error = 0
  10726.     def showsyntaxerror(self, *args, **kargs):
  10727.         self.error = 1
  10728.         return code.InteractiveInterpreter.showsyntaxerror(self, *args, **kargs)
  10729.     def showtraceback(self, *args, **kargs):
  10730.         self.error = 1
  10731.         return code.InteractiveInterpreter.showtraceback(self, *args, **kargs)
  10732.  
  10733.  
  10734. def autorun_commands(cmds,verb=0):
  10735.     sv = conf.verb
  10736.     try:
  10737.         conf.verb = verb
  10738.         interp = ScapyAutorunInterpreter(globals())
  10739.         cmd = ""
  10740.         cmds = cmds.splitlines()
  10741.         cmds.append("") # ensure we finish multiline commands
  10742.         cmds.reverse()
  10743.         while 1:
  10744.             if cmd:
  10745.                 sys.stderr.write(sys.__dict__.get("ps2","... "))
  10746.             else:
  10747.                 sys.stderr.write(str(sys.__dict__.get("ps1",ColorPrompt())))
  10748.                 
  10749.             l = cmds.pop()
  10750.             print l
  10751.             cmd += "\n"+l
  10752.             if interp.runsource(cmd):
  10753.                 continue
  10754.             if interp.error:
  10755.                 return 0
  10756.             cmd = ""
  10757.             if len(cmds) <= 1:
  10758.                 break
  10759.     finally:
  10760.         conf.verb = sv
  10761.     try:
  10762.         return _
  10763.     except NameError:
  10764.         return
  10765.  
  10766. def autorun_get_interactive_session(cmds):
  10767.     class StringWriter:
  10768.         def __init__(self):
  10769.             self.s = ""
  10770.         def write(self, x):
  10771.             self.s += x
  10772.             
  10773.     sw = StringWriter()
  10774.     sstdout,sstderr = sys.stdout,sys.stderr
  10775.     try:
  10776.         sys.stdout = sys.stderr = sw
  10777.         res = autorun_commands(cmds)
  10778.     finally:
  10779.         sys.stdout,sys.stderr = sstdout,sstderr
  10780.     return sw.s,res
  10781.  
  10782. def autorun_get_text_interactive_session(cmds):
  10783.     ct = conf.color_theme
  10784.     try:
  10785.         conf.color_theme = NoTheme()
  10786.         s,res = autorun_get_interactive_session(cmds)
  10787.     finally:
  10788.         conf.color_theme = ct
  10789.     return s,res
  10790.  
  10791. def autorun_get_ansi_interactive_session(cmds):
  10792.     ct = conf.color_theme
  10793.     try:
  10794.         conf.color_theme = DefaultTheme()
  10795.         s,res = autorun_get_interactive_session(cmds)
  10796.     finally:
  10797.         conf.color_theme = ct
  10798.     return s,res
  10799.  
  10800. def autorun_get_html_interactive_session(cmds):
  10801.     ct = conf.color_theme
  10802.     try:
  10803.         conf.color_theme = HTMLTheme2()
  10804.         s,res = autorun_get_interactive_session(cmds)
  10805.     finally:
  10806.         conf.color_theme = ct
  10807.     
  10808.     s = s.replace("<","<").replace(">",">").replace("#[#","<").replace("#]#",">")
  10809.     return s,res
  10810.  
  10811. def autorun_get_latex_interactive_session(cmds):
  10812.     ct = conf.color_theme
  10813.     try:
  10814.         conf.color_theme = LatexTheme2()
  10815.         s,res = autorun_get_interactive_session(cmds)
  10816.     finally:
  10817.         conf.color_theme = ct
  10818.     s = tex_escape(s)
  10819.     s = s.replace("@[@","{").replace("@]@","}").replace("@`@","\\")
  10820.     return s,res
  10821.  
  10822.  
  10823. ################
  10824. ##### Main #####
  10825. ################
  10826.  
  10827. def scapy_write_history_file(readline):
  10828.     if conf.histfile:
  10829.         readline.write_history_file(conf.histfile)
  10830.  
  10831.  
  10832. def interact(mydict=None,argv=None,mybanner=None,loglevel=1):
  10833.     import code,sys,cPickle,types,os,imp,getopt,logging
  10834.  
  10835.     logging.getLogger("scapy").setLevel(loglevel)
  10836.  
  10837.     the_banner = "Welcome to Scapy (%s)"
  10838.     if mybanner is not None:
  10839.         the_banner += "\n"
  10840.         the_banner += mybanner
  10841.  
  10842.     if argv is None:
  10843.         argv = sys.argv
  10844.  
  10845. #    scapy_module = argv[0][argv[0].rfind("/")+1:]
  10846. #    if not scapy_module:
  10847. #        scapy_module = "scapy"
  10848. #    else:
  10849. #        if scapy_module.endswith(".py"):
  10850. #            scapy_module = scapy_module[:-3]
  10851. #
  10852. #    scapy=imp.load_module("scapy",*imp.find_module(scapy_module))
  10853.     
  10854.     
  10855.     import __builtin__
  10856. #    __builtin__.__dict__.update(scapy.__dict__)
  10857.     __builtin__.__dict__.update(globals())
  10858.     if mydict is not None:
  10859.         __builtin__.__dict__.update(mydict)
  10860.  
  10861.  
  10862.     import re, atexit
  10863.     try:
  10864.         import rlcompleter,readline
  10865.     except ImportError:
  10866.         log_loading.info("Can't load Python libreadline or completer")
  10867.         READLINE=0
  10868.     else:
  10869.         READLINE=1
  10870.         class ScapyCompleter(rlcompleter.Completer):
  10871.             def global_matches(self, text):
  10872.                 matches = []
  10873.                 n = len(text)
  10874.                 for lst in [dir(__builtin__), session.keys()]:
  10875.                     for word in lst:
  10876.                         if word[:n] == text and word != "__builtins__":
  10877.                             matches.append(word)
  10878.                 return matches
  10879.         
  10880.     
  10881.             def attr_matches(self, text):
  10882.                 m = re.match(r"(\w+(\.\w+)*)\.(\w*)", text)
  10883.                 if not m:
  10884.                     return
  10885.                 expr, attr = m.group(1, 3)
  10886.                 try:
  10887.                     object = eval(expr)
  10888.                 except:
  10889.                     object = eval(expr, session)
  10890.                 if isinstance(object, Packet):
  10891.                     words = filter(lambda x: x[0]!="_",dir(object))
  10892.                     words += map(str, object.fields_desc)
  10893.                 else:
  10894.                     words = dir(object)
  10895.                     if hasattr( object,"__class__" ):
  10896.                         words = words + rlcompleter.get_class_members(object.__class__)
  10897.                 matches = []
  10898.                 n = len(attr)
  10899.                 for word in words:
  10900.                     if word[:n] == attr and word != "__builtins__":
  10901.                         matches.append("%s.%s" % (expr, word))
  10902.                 return matches
  10903.     
  10904.         readline.set_completer(ScapyCompleter().complete)
  10905.         readline.parse_and_bind("C-o: operate-and-get-next")
  10906.         readline.parse_and_bind("tab: complete")
  10907.     
  10908.     
  10909.     session=None
  10910.     session_name=""
  10911.  
  10912.     opts=getopt.getopt(argv[1:], "hs:")
  10913.     iface = None
  10914.     try:
  10915.         for opt, parm in opts[0]:
  10916.         if opt == "-h":
  10917.             usage()
  10918.             elif opt == "-s":
  10919.                 session_name = parm
  10920.         
  10921.     if len(opts[1]) > 0:
  10922.         raise getopt.GetoptError("Too many parameters : [%s]" % string.join(opts[1]),None)
  10923.  
  10924.  
  10925.     except getopt.error, msg:
  10926.         log_loading.error(msg)
  10927.         sys.exit(1)
  10928.  
  10929.  
  10930.     if session_name:
  10931.         try:
  10932.             os.stat(session_name)
  10933.         except OSError:
  10934.             log_loading.info("New session [%s]" % session_name)
  10935.         else:
  10936.             try:
  10937.                 try:
  10938.                     session = cPickle.load(gzip.open(session_name))
  10939.                 except IOError:
  10940.                     session = cPickle.load(open(session_name))
  10941.                 log_loading.info("Using session [%s]" % session_name)
  10942.             except EOFError:
  10943.                 log_loading.error("Error opening session [%s]" % session_name)
  10944.             except AttributeError:
  10945.                 log_loading.error("Error opening session [%s]. Attribute missing" %  session_name)
  10946.  
  10947.         if session:
  10948.             if "conf" in session:
  10949.                 conf.configure(session["conf"])
  10950.                 session["conf"] = conf
  10951.         else:
  10952.             conf.session = session_name
  10953.             session={"conf":conf}
  10954.             
  10955.     else:
  10956.         session={"conf": conf}
  10957.  
  10958.     __builtin__.__dict__["scapy_session"] = session
  10959.  
  10960.  
  10961.     if READLINE:
  10962.         if conf.histfile:
  10963.             try:
  10964.                 readline.read_history_file(conf.histfile)
  10965.             except IOError:
  10966.                 pass
  10967.         atexit.register(scapy_write_history_file,readline)
  10968.     
  10969.     sys.ps1 = ColorPrompt()
  10970.     code.interact(banner = the_banner % (VERSION), local=session)
  10971.  
  10972.     if conf.session:
  10973.         save_session(conf.session, session)
  10974.     
  10975.     sys.exit()
  10976.  
  10977. if __name__ == "__main__":
  10978.     interact()
  10979.